![]() |
Bilder vergleichen
hi all,
ich suche nach einer möglichkeit zwei bilder zu vergeleichen? Kann mir da jemand helfen? Danke im voraus! |
Re: Bilder vergleichen
Kommt drauf an. Wann sind denn für dich Bilder gleich? Wenn sie Pixel für Pixel übereinstimmen? dann hol die Mit ScanLine jedes Pixel und vergleiche.
|
Re: Bilder vergleichen
Gibt zwei Varianten.
1) Du vergleichst die Dateien binär - d.h. sie müssen absolut gleich sein, um als gleich zu gelten. 2) Pixel-by-Pixel vergleichen, oder beser noch von jedem Pixel jeweils r-, g- und b-Anteil vergleichen. Dort kann man dann 2 Arten von Toleranz einbauen. Einmal eine per-Channel-per-Pixel Toleranz, das heisst wenn ein Pixel in einem Bild etwas dunkler ist, aber der Farbwert sonst recht gut hinkommt, werden sie als gleich angesehen. (gut bei Vergleichen von bmp's mit jpeg's). Oder man prüft auf absolute Pixelgleichheit und zählt mit viel viele Pixel gleich sind. Bei z.B. 80% Gleichheit gelten die Bilder als gleich. Jetzt könnte man das auch kombinieren: Es wird tolerant by-Channel (by-Farbkanal = r, g, b) verglichen, und wenn die toleranz überschritten ist werden die ungleichen mitgezählt. Dann noch Verfahren 2 anwenden, und bei 90% toleranter Pixel-Channel-Gleichheit sind die Bilder dann gleich. Mit den Schwellenwerten muss man ein wenig expeimentieren um verlässliche Ergebnisse zu erhalten. gruss, dizzy |
Re: Bilder vergleichen
harifg dürfte die Angelegenheit allerdings werden wenn dein code z.B. Ausschnitte oder verzerrungen auch zulassen soll. irgendwann hab ich ml ein bisschen sowas gebaut, das ging dann damit, dass er versucht hat formen zu erkennen (also formen >5% bildfläche). Das hab ich dann so gemacht, dass ich das bild erst sehr stark verwischt hab (besonders in Bezug auf einzelne pixel die stark heraustreten) Danach hab ich dann das bild abgetastetund versucht dreiecke reinzulegen. Haben diese dreiecke bei beiden bildern dann halbwegs übereingestimmt hat mein code gleich ausgegeben. war aber ein nettes Stück Arbeit...
|
Re: Bilder vergleichen
Das ist dann ja schon fast Vektorisierung...
Habe bei meinem Vergleicher auch zunächst getestet, od das Seitenverhältnis der zwei Probanden in etwa hinkommt, und dann hab ich das größere auf die Größe des kleines skaliert, und DANN tolerant pixelweise getestet. Bei Gleichheit hab ich auch das kleinere dann direkt in einen "zu löschen"-Ordner gepackt, damit man vorm endgültigen Löschen noch mal besser gucken kann. Auch ein Delete-Log hab ich mitgeführt, so dass man nachsehen kann, welche Dateien/Bilder als gleich gelten, und welches der Beiden quasi-gelöscht ist. Wollte noch eine direkte Vergleichsmöglichkeit in mein Programm bauen, ist aber mangels Zeit und wegen eines grundsätzlichen Problems mit TJPGImage+Threads zum Erliegen gekommen... gruss, dizzy |
Re: Bilder vergleichen
Delphi-Quellcode:
Das war jetzt mein erster gehversuch mit ScanLine.
procedure TForm1.Button1Click(Sender: TObject);
var i,w,r,x : integer ; BitMap, BitMap2 : TBitMap; P,P2 : PByteArray; begin BitMap := TBitMap.create; BitMap2 := TBitMap.create; BitMap.LoadFromFile('vorlage.bmp'); //Laden der ausgangsdatei BitMap2.LoadFromFile('screenshot.bmp'); //Laden der vergleichsdatei r := 0; w := 0; for i := 0 to BitMap.Height - 1 do begin P := BitMap.ScanLine[i]; P2 := BitMap2.ScanLine[i]; if p = p2 then r := r + 1 //anzahl gleicher Lines else w := w + 1; //anzahl unterschiedlicher lines end; Label1.caption := InttoStr(r); Label2.caption := IntToStr(w); end; Aber selbst wenn ich zwei verschiedene Dateien (auflösung ist die selbe) nutze kommt immer das ergebnis bei raus das diese dateien an keiner stelle übereinstimmen. Kann mir da jemand etwas nachhelfen? Danke schon mal im voraus. :oops: |
Re: Bilder vergleichen
hi,
Vielleicht hilft dir ja dies:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var b1, b2: TBitmap; c1, c2: PByte; x, y, i, different: Integer; // Counter for different pixels begin b1 := Image1.Picture.Bitmap; b2 := Image2.Picture.Bitmap; Assert(b1.PixelFormat = b2.PixelFormat); // they have to be equal different := 0; for y := 0 to b1.Height - 1 do begin c1 := b1.Scanline[y]; c2 := b2.Scanline[y]; for x := 0 to b1.Width - 1 do for i := 0 to BytesPerPixel - 1 do // 1, to 4, dep. on pixelformat begin Inc(different, Integer(c1^ <> c2^)); Inc(c1); Inc(c2); end; end; end; ![]() |
Re: Bilder vergleichen
Zitat:
P & P2 sind lediglich 2 Zeiger, die natürlich bei 2 Bitmaps immer verschieden sind. Deshalb:
Delphi-Quellcode:
for j:= 0 to BitMap.Width - 1 do
if P[j] = P2[j] then Inc(r) //anzahl gleicher Pixel else Inc(w); //anzahl unterschiedlicher Pixel |
Re: Bilder vergleichen
p und p2 sind nur Zeiger auf die Array's (ScanLine's) und diese sind immer unterschiedlich, da die beiden Array's nie den selben Speicherplatz verwenden ;)
Du muß also die Daten vergleichen - ich hoffe mal, dass es mit CompareMem geht.
Delphi-Quellcode:
notfalls kann man's auch Byteweise vergleichen:
procedure TForm1.Button1Click(Sender: TObject);
var i,w,r,x : integer ; BitMap, BitMap2 : TBitMap; P,P2 : PByteArray; begin BitMap := TBitMap.create; BitMap2 := TBitMap.create; BitMap.LoadFromFile('vorlage.bmp'); //Laden der ausgangsdatei BitMap2.LoadFromFile('screenshot.bmp'); //Laden der vergleichsdatei r := 0; w := 0; for i := 0 to BitMap.Height - 1 do begin P := BitMap.ScanLine[i]; P2 := BitMap2.ScanLine[i]; if (Length(P) = Length(P2)) and CompareMem(P, P2, Length(P)) then r := r + 1 //anzahl gleicher Lines else w := w + 1; //anzahl unterschiedlicher lines end; Label1.caption := InttoStr(r); Label2.caption := IntToStr(w); end;
Delphi-Quellcode:
(Angaben ohne Waffen)
for i := 0 to BitMap.Height - 1 do
begin P := BitMap.ScanLine[i]; P2 := BitMap2.ScanLine[i]; B := Length(P) = Length(P2); if B then for i2 := 0 to Length(P) - 1 do if P[i2] <> P2[i2] then begin B := false; break; end; if B then r := r + 1 //anzahl gleicher Lines else w := w + 1; //anzahl unterschiedlicher lines end; [add] ich sollte mal aufhören was nebenbei zu machen ![]() |
Re: Bilder vergleichen
Hi,
hab das eben gerade mal getestet..... leider funzt diese Zeile:
Delphi-Quellcode:
Nicht....... imkompatible Typen..... ich überleg schon die ganzen Zeit, wie man das konvertieren könnte, bzw. wie man den die Länge sonst noch "bekommen" könnte..... :gruebel:
Length(P)
Weiss jemand mehr?! Ricane |
Re: Bilder vergleichen
versuchs mal mit
Delphi-Quellcode:
mfG
High(P^)
mirage228 |
Re: Bilder vergleichen
Mmhhhhh........ ne, funzt auch nicht..... Fehlermeldung hält sich beständig :gruebel:
EDIT: Sorry! Das mit dem High klappt..... war ein Fehler von mir :oops: |
Re: Bilder vergleichen
Also bei mir gehts.
Mein Test-Code:
Delphi-Quellcode:
Der Compiler hat jetzt nur auszusetzen gehabt, das P und P2 nicht intialisert waren. Sonst gabs keine Fehler.
var
P,P2 : PByteArray; i: integer; begin i := High(P^); CompareMem(P, P2, High(P^)); mfG mirage228 P.S.: TByteArray hat eine feste Länge von 32768 [0..32767] |
Re: Bilder vergleichen
och menno, mußt du doch tatsächlich sowas altes ausgraben und dann auchnoch behaupten es ginge nicht :?
:coder2: Na dann werd' ich wohl mal nachgucken müssen |
Re: Bilder vergleichen
Aber irgendwie krieg ich trotzdem immer eine Exception, das aus einem Bereich nicht gelesen werden kann...... hier mein Code ...
Der Fehler tritt bei dem CompareMem Befehl auf...
Delphi-Quellcode:
Lanege hat fast immer den Wert von 32767... was ja eigentlich total ok ist...
Var
I, J, K, Laenge: Integer; Reihe: Array[1..2] Of PByteArray; Ungleich: Array[1..4] Of Boolean; [...] Begin [...] For K := 1 To 4 Do Begin For J := 0 To AktBmp[K].Height - 1 Do Begin Reihe[1] := AktBmp[K].ScanLine[J]; Reihe[2] := AltBmp[K].ScanLine[J]; Laenge := High(Reihe[2]^); If CompareMem(Reihe[1], Reihe[2], Laenge) = False Then Ungleich[K] := True; If Ungleich[K] = True Then Break; End; End [...] End; *Ricane-der-alte-Thread-Ausgräber* |
Re: Bilder vergleichen
Also PByteArray ist ein Zeiger auf TByteArray und TByteArray ist als "Array[0..32767] of Byte" definiert.
Length(P) hätte eh nicht funktioniert, da P ein Pointer ist und immer 4 Byte (derzeit) ist So, das mit CompareMem läuft jetzt:
Delphi-Quellcode:
Procedure TForm1.Button1Click(Sender: TObject);
Var i, R, W, L, X: Integer; BitMap, BitMap2: TBitMap; Begin BitMap := TBitMap.create; BitMap2 := TBitMap.create; BitMap.LoadFromFile('vorlage.bmp'); //Laden der ausgangsdatei BitMap2.LoadFromFile('screenshot.bmp'); //Laden der vergleichsdatei If BitMap.PixelFormat <> BitMap2.PixelFormat Then Label1.Caption := 'unterschiedliches Pixelformat' Else If (BitMap.Width <> BitMap2.Width) and (BitMap.Height <> BitMap2.Height) Then Label1.Caption := 'unterschiedliche Bildgröße' Else Begin R := 0; W := 0; Case BitMap.PixelFormat of pf1bit: L := Ceil(BitMap.Width / 8); pf4bit: L := Ceil(BitMap.Width / 2); pf8bit: L := BitMap.Width; pf15bit: L := Ceil(BitMap.Width * 15 / 8); {ich hoffe mal das für die 15 Bit stimmt} pf16bit: L := BitMap.Width * 2; pf24bit: L := BitMap.Width * 3; pf32bit: L := BitMap.Width * 4; End; For i := 0 to BitMap.Height - 1 do If CompareMem(BitMap.ScanLine[i], BitMap2.ScanLine[i], L) Then Inc(R) Else Inc(W); Label1.Caption := IntToStr(R) + ' gleiche und ' + IntToStr(W) + ' unterschiedliche Zeilen'; End; End; |
Re: Bilder vergleichen
*ausgrab*
und was muss ich machen, wenn das PixelFormat meines Bitmaps auf pfDevice steht? Kann ich den Code dahingehend erweitern, oder soll ich einfach das Pixelformat meiner Bitmaps verändern (da ich sie selber erstelle, sollte das kein Problem sein) und wenn ja, was soll ich für ein Pixelformat verwenden? |
Re: Bilder vergleichen
Hi Leute bei mir komm die Fehlermeldung "[Fehler] Unit1.pas(78): Undefinierter Bezeichner: 'Ceil'"
Code:
Delphi-Quellcode:
hab schon die ganze Zeit herumprobiert finde keine Lösung.
procedure vergleichenb;
var b1, b2: TBitmap; c1, c2: PByte; x, y, i, different: Integer; // Counter for different pixels Var R, W, L: Integer; begin b1 := Form1.Image1.Picture.Bitmap; b2 := Form1.spielerk.Picture.Bitmap; If b1.PixelFormat <> b2.PixelFormat Then Form1.Label1.Caption := 'unterschiedliches Pixelformat' Else If (b1.Width <> b1.Width) and (b2.Height <> b2.Height) Then Form1.Label1.Caption := 'unterschiedliche Bildgröße' Else Begin R := 0; W := 0; Case b1.PixelFormat of pf1bit: L := Ceil(b1.Width / 8); pf4bit: L := Ceil(b1.Width / 2); pf8bit: L := b1.Width; pf15bit: L := Ceil(b1.Width * 15 / 8); {ich hoffe mal das für die 15 Bit stimmt} pf16bit: L := b1.Width * 2; pf24bit: L := b1.Width * 3; pf32bit: L := b1.Width * 4; rnd; For i := 0 to b1.Height - 1 do If CompareMem(b1.ScanLine[i], b2.ScanLine[i], L) Then Inc(R) Else Inc(W); Form1.Label1.Caption := IntToStr(R) + ' gleiche und ' + IntToStr(W) + ' unterschiedliche Zeilen'; end; end; Danke für euere Anworten im Voraus godman |
Re: Bilder vergleichen
Habe zwar keine Lösung für dein Problem, aber du kannst mal
![]() |
Re: Bilder vergleichen
ich muss zwei jpgs vergleichen?
welcher Code funzt nun? |
Re: Bilder vergleichen
Ich habe auch mal sowas gemacht und es so programmiert das nicht etwa "gleich", "nicht gleich" etc. ausgegeben wird, sonder zu wieviel Prozent die Bilder übereinstimmen. Dann kann sich der Anwender einen eigenen Reim machen ob die Bilder jetzt gleich sind oder nicht :wink:
|
Re: Bilder vergleichen
könntet du es hier posten?
achja, ich muss jpgs vergleichen! |
Re: Bilder vergleichen
:wink: wenns fertig ist kann da mal jmd. eine Demo hochladen? Ist nämlich ein interessantes Thema..
|
Re: Bilder vergleichen
Was ich hier so sehe, sucht doch alle VOLLKOMMEN gleichen Pixel. Man könnte doch auch die Differenz zwischen den Farben nehmen (Betragsweise oder nicht, hängt davon ab wie mans will), addieren ev. dann den Mittelwert nehmen und dann muss es sich in einem bestimmten Bereich befinden...
LG, ich |
Re: Bilder vergleichen
hat niemand ne lösung?
ich bräuchte was furchtbar dringend!!! :( |
Re: Bilder vergleichen
Hier sind doch sogar gleich zwei fertige Lösungen erwähnt :gruebel: . Einmal himitsus Funktion und einmal turboPascals Projekt. Mindestens eine von diesen wird doch wohl funktionieren.
|
Re: Bilder vergleichen
omg.....
sry, aba ich werd von dem, was da oben steht nicht schlau..... alles was ich will ist, 2 bmp bilder zu vergleichen.... die höhe und breite der bilder sind gleich.... brauch die ähnlichkeitn nur grob... um ein memory-spiel zu programieren.... (wenn bild 1 und bild 2 gleich sind dannn usw...) wär nett wenn ihr da was einfaches wüsstet.... thx |
Re: Bilder vergleichen
Also für n Memory-Spiel würd ich keine Pixel vergleichen... ich würde da zwei gleichen TImages einfach das gleiche TControl.Tag verpassen!
|
Re: Bilder vergleichen
Dann gib den Komponenten, mit denen du die Karten anzeigst, doch einen Wert für die Tag-Eigenschaft, womit du angibst, welches Bild darin liegt (also ein Index), anstatt die Bilder als Pixelgrafiken zu vergleichen, oder spricht da was dagegen :gruebel:
LG, ich Edit: Wo bleibt der rote Kasten :gruebel: |
Re: Bilder vergleichen
Zitat:
nur ich hab net so viel ahnung davon.... naja... es reicht zwar für 10 punkte im unterricht aba ich hab kA wie ich das machen soll... glaub, das reicht auch, wennsch nur die dateinamen vergleiche... oda? wie geht das? plz da weiterposten: ![]() |
Re: Bilder vergleichen
Du solltest nicht zwei thrads zum selben thema aufmachen..
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:50 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz