Delphi-PRAXiS

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

SCHNICO 13. Mär 2004 08:01


Bilder vergleichen
 
hi all,

ich suche nach einer möglichkeit zwei bilder zu vergeleichen? Kann mir da jemand helfen?

Danke im voraus!

Luckie 13. Mär 2004 08:03

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.

dizzy 13. Mär 2004 15:31

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

MathiasH 15. Mär 2004 14:53

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...

dizzy 15. Mär 2004 15:02

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

SCHNICO 18. Mär 2004 17:05

Re: Bilder vergleichen
 
Delphi-Quellcode:
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;
Das war jetzt mein erster gehversuch mit ScanLine.
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:

toms 18. Mär 2004 17:10

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;
(c) by SwissDelphiCenter

shmia 18. Mär 2004 17:19

Re: Bilder vergleichen
 
Zitat:

Zitat von SCHNICO
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;

Das kann so nicht funktionieren.
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

himitsu 18. Mär 2004 17:26

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:
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;
notfalls kann man's auch Byteweise vergleichen:
Delphi-Quellcode:
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;
(Angaben ohne Waffen)

[add]
ich sollte mal aufhören was nebenbei zu machen http://FNSE.de/15C.gif

Ricane 8. Sep 2004 19:34

Re: Bilder vergleichen
 
Hi,

hab das eben gerade mal getestet..... leider funzt diese Zeile:

Delphi-Quellcode:
Length(P)
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:


Weiss jemand mehr?!

Ricane

mirage228 8. Sep 2004 19:35

Re: Bilder vergleichen
 
versuchs mal mit

Delphi-Quellcode:
High(P^)
mfG
mirage228

Ricane 8. Sep 2004 19:41

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:

mirage228 8. Sep 2004 19:54

Re: Bilder vergleichen
 
Also bei mir gehts.

Mein Test-Code:
Delphi-Quellcode:
var
  P,P2 : PByteArray;
  i: integer;
begin
  i := High(P^);
  CompareMem(P, P2, High(P^));
Der Compiler hat jetzt nur auszusetzen gehabt, das P und P2 nicht intialisert waren. Sonst gabs keine Fehler.

mfG
mirage228

P.S.: TByteArray hat eine feste Länge von 32768 [0..32767]

himitsu 8. Sep 2004 19:55

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

Ricane 8. Sep 2004 20:05

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:
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;
Lanege hat fast immer den Wert von 32767... was ja eigentlich total ok ist...


*Ricane-der-alte-Thread-Ausgräber*

himitsu 8. Sep 2004 20:31

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;

xineohp 5. Feb 2005 21:40

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?

godman 27. Nov 2005 19:22

Re: Bilder vergleichen
 
Hi Leute bei mir komm die Fehlermeldung "[Fehler] Unit1.pas(78): Undefinierter Bezeichner: 'Ceil'"

Code:

Delphi-Quellcode:
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;
hab schon die ganze Zeit herumprobiert finde keine Lösung.

Danke für euere Anworten im Voraus

godman

turboPASCAL 27. Nov 2005 22:47

Re: Bilder vergleichen
 
Habe zwar keine Lösung für dein Problem, aber du kannst mal hier (Bitmap Compare) sachauen. Diese Lösung ist zwar einfach aber gut und mit Features. ( Werbung ;) )

marlem 26. Apr 2006 15:02

Re: Bilder vergleichen
 
ich muss zwei jpgs vergleichen?
welcher Code funzt nun?

robinWie 26. Apr 2006 15:41

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:

marlem 26. Apr 2006 15:46

Re: Bilder vergleichen
 
könntet du es hier posten?
achja, ich muss jpgs vergleichen!

EDatabaseError 26. Apr 2006 15:51

Re: Bilder vergleichen
 
:wink: wenns fertig ist kann da mal jmd. eine Demo hochladen? Ist nämlich ein interessantes Thema..

Delphi-Freak 26. Apr 2006 16:59

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

marlem 27. Apr 2006 13:53

Re: Bilder vergleichen
 
hat niemand ne lösung?
ich bräuchte was furchtbar dringend!!! :(

Khabarakh 27. Apr 2006 14:05

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.

win98 6. Jun 2006 15:02

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

DGL-luke 6. Jun 2006 15:05

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!

Delphi-Freak 6. Jun 2006 15:07

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:

win98 6. Jun 2006 15:07

Re: Bilder vergleichen
 
Zitat:

Zitat von DGL-luke
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!

jo denk ma auch....


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:
http://www.delphipraxis.net/internal...=559504#559504

DGL-luke 6. Jun 2006 15:18

Re: Bilder vergleichen
 
Du solltest nicht zwei thrads zum selben thema aufmachen..


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:10 Uhr.

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