Delphi-PRAXiS
Seite 2 von 5     12 34     Letzte »    

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi Bilder schnell miteinander vergleichen (https://www.delphipraxis.net/80639-bilder-schnell-miteinander-vergleichen.html)

alzaimar 13. Nov 2006 18:32

Re: Bilder schnell miteinander vergleichen
 
Wenn Du wissen willst, ob zwei Bilder identisch sind, oder nicht, dann reicht dieser Code:
Delphi-Quellcode:
Function CompareBitmap (Bitmap1, Bitmap2 : TBitmap) : Integer;
  If CompareMem (Bitmap1.Scanline[Bitmap1.Height - 1], Bitmap2.ScanLine [Bitmap2.Height - 1], Bitmap1.Width*Bitmap1.Height*SizeOf(TRGBTriple)) Then
    Result := 0
  Else
    Result := 1
End;
Dieses Fragment liefert 1, wenn die Bitmaps ungleich sind und 0, wenn sie identisch sind. Das ist nochmal 10% schneller als Dein Code. Die Voraussetzungen sind die Gleichen: Gleiche Auflösung, gleiche Größe, gleiches Pixelformat.

Mit FastCode (siehe FastCode.Sourceforge.net) kannst Du dann nochmal 20% rausholen...

Phantom1 13. Nov 2006 18:36

Re: Bilder schnell miteinander vergleichen
 
Ich hab das jetzt nochmal nachgeprüft und muss alzaimar recht geben, dein Algo ist schneller wenn die Bilder nur wenige oder garkeine unterschiede haben, das ganze dreht sich aber um wenn es sehr viele unterschiede gibt oder wenn komplett verschiedene bilder miteinander verglichen werden.

Gleiche Bilder vergleichen (500 durchläufe):
dein Algo: 1 sek
mein Algo: 1,7 sek

zwei komplett unterschiedliche Bilder vergleichen (500 Durchläufe):
dein Algo: 3,7 sek
mein Algo: 1,7 sek

Damit sollte die sache geklärt sein :wink:

@Alzaimar: was ist wenn er wirklich wissen muss wieviele unterschiede in 2 Bildern vorhanden sind? Was er genau damit machen will wissen wir ja nicht genau.

mfg

shmia 13. Nov 2006 18:56

Re: Bilder schnell miteinander vergleichen
 
Hier ist mein (ungetesteter) Vorschlag.
Es hat folgende Vorteile:
* man kann eine Maske angeben, um Farbunterschiede unterhalb einer bestimmten Grenze auszublenden
* durch Verwendung von Zeigern wird der Vergleich schneller
* die innere Schleife ist schneller, da sie auf 0 runterzählt
* der Code ist "kurz & knackig"
Delphi-Quellcode:
function CompareImagesShmia(Image1,Image2:TBitmap; mask:Cardinal=$00FEFEFE):Int64;
var x,y:integer;
    P1,P2: PByte;
begin
result := 0;
for y := 0 to Image1.Height -1 do
  begin
    P1 := Image1.ScanLine[y];
    P2 := Image2.ScanLine[y];

    for x := Image1.Width-1 downto 0 do
    begin
      if (PInteger(P1)^ and mask) <> (PInteger(P2)^ and mask) then
        inc(result);
      Inc(P1, 3); Inc(P2, 3);
    end;
  end;
end;
Nachtrag:
die Variable mask muss evtl. mit $FEFEFE00 vorbelegt werden.
Für den Vergleich werden ja 4 Bytes=Integer gelesen; es kommt nun drauf an,
ob das überzählige Byte MSB oder LSB ist.

alzaimar 13. Nov 2006 19:03

Re: Bilder schnell miteinander vergleichen
 
Zitat:

Zitat von Phantom1
@Alzaimar: was ist wenn er wirklich wissen muss wieviele unterschiede in 2 Bildern vorhanden sind? Was er genau damit machen will wissen wir ja nicht genau.
mfg

Das der Algo die Anzahl der unterschiedlichen Pixel zurückliefert, ist irgendwie klar :zwinker: , aber der Sinn ist nicht ersichtlich. Wozu? Wann sind Bilder in Auflösung, Größe und Farbtiefe absolut vergleichbar? Na ja, Anwendungen gibts bestimmt, hast schon recht :roll:

Phantom1 13. Nov 2006 19:47

Re: Bilder schnell miteinander vergleichen
 
@shima: dein Code bringt eine AV, du hast die Pointer P1 und P2 als PByte und inkrementierst diese bei der x-schleife mit 3

mfg

Airblader 13. Nov 2006 23:12

Re: Bilder schnell miteinander vergleichen
 
Ich kenn mich zwar nicht allzugut darin aus, aber wandelt der Borlandcompiler Schleifen nicht immer in ein downto um? (Ergo ist es egal ob ich es als downto hinschreibe oder nicht).

air

mbamler 14. Nov 2006 06:58

Re: Bilder schnell miteinander vergleichen
 
Zitat:

Zitat von Airblader
Ich kenn mich zwar nicht allzugut darin aus, aber wandelt der Borlandcompiler Schleifen nicht immer in ein downto um? (Ergo ist es egal ob ich es als downto hinschreibe oder nicht).

air

Das tut er - zumindest, wenn die Compiler-Optimierungen eingeschaltet sind...

Gruß
Matthias

shmia 14. Nov 2006 09:55

Re: Bilder schnell miteinander vergleichen
 
Zitat:

Zitat von Phantom1
@shima: dein Code bringt eine AV, du hast die Pointer P1 und P2 als PByte und inkrementierst diese bei der x-schleife mit 3

Natürlich müssen die Bitmaps im 24Bit-Format vorliegen. (bitmap.PixelFormat := pf24bit)
Ein Pixel benötigt 24Bit = 3 Bytes; daher werden die Zeiger jeweils um 3 Bytes inkrementiert.

Phoenix 14. Nov 2006 10:08

Re: Bilder schnell miteinander vergleichen
 
Zitat:

Zitat von alzaimar
Viel interessanter wäre es, einen Ähnlichkeitsindex von zwei beliebigen Bildern zu erstellen, die unterschiedlich kodiert (JPEG vs. BMP) und in unterschiedlichen Farbtiefen und Auflösungen vorliegen.

Was auch nicht so hyperkompliziert ist. Das wichtigste ist erstmal eine mehr oder weniger saubere Kanten- und Flächenerkennung, die Umrechnung dieser erkannten Kanten in Vektoren und dann die Vergleiche der enstprechenden Vektoren zusammen mit einem Farbvergleich der umschlossenen Flächen.

Daraus kann man dann mit einer gewissen Genauigkeit darauf schliessen, ob verschiedene Bilder das gleiche Motiv zeigen oder nicht, oder ob sie das gleiche Motiv mit einer verschobenen Position zeigen.

Alternativ kann man auch einfach einen Bildausschnitt nehmen (z.B. ein kleines Quadrat) und das dann auf dem nächsten Bild solange herumschieben bis es wieder ein Treffer ist. Das setzt aber wieder gleiche Auflösung und Farbtiefe voraus. Mit diesem Verfahren wird übrigens in MPEG-Videocodes ermittelt welche Bereiche im folgenden Bild aus Teilen des Vorherigen bestehen und dann wird komprimiert in dem gesagt wird: Der Ausschnitt (x,y, breite,höhe) aus Bild X kommt an diese Position (x,y) in Bild Y. Spart massigst Daten :)

Phantom1 14. Nov 2006 10:10

Re: Bilder schnell miteinander vergleichen
 
Zitat:

Zitat von shmia
Natürlich müssen die Bitmaps im 24Bit-Format vorliegen. (bitmap.PixelFormat := pf24bit)
Ein Pixel benötigt 24Bit = 3 Bytes; daher werden die Zeiger jeweils um 3 Bytes inkrementiert.

Das ist mir schon klar, aber dein Code bringt eine AV.

so sieht deine x-schleife aus
Delphi-Quellcode:
for x := Image1.Width-1 downto 0 do
ich vermute mal du wolltest es so hier machen, dann müsste dein code glaub ich gehen:
Delphi-Quellcode:
for x := Image1.Width div 3-1 downto 0 do
mfg


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:14 Uhr.
Seite 2 von 5     12 34     Letzte »    

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz