Autor |
Beitrag |
HenryHux
      
Beiträge: 542
Erhaltene Danke: 33
Windows 7 Premium
Delphi XE, Eclipse
|
Verfasst: Do 23.09.10 13:30
Hi,
ich habe ja mit eurer Hilfe mitlerweile ein Programm hinbekommen, welches Bilder vergleiche kann. Klappt auch 1A!
Jetzt versuche ich aber ein Bild mit ca 50 verschiedenen zu vergleichen. Wie realisiere ich das am besten? Ich kann ja nicht schlecht 50 TImage erzeugen, oder?
Hier die Funktion, die die Bilder vergleicht :
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16:
| function CompareImages(Bitmap3, Bitmap2: TBitmap): LongWord; var xy: integer; P1, P2: PInteger; begin Result:=0; Bitmap3.PixelFormat:=pf32bit; Bitmap2.PixelFormat:=pf32bit; P1:=Bitmap3.ScanLine[Bitmap3.Height-1]; P2:=Bitmap2.ScanLine[Bitmap2.Height-1]; for xy:=1 to Bitmap3.Height*Bitmap3.Width do begin Inc(Result, Byte(P1^<>P2^)); Inc(P1); Inc(P2); end; end; |
Und hier die, die sie aufruft:
Delphi-Quelltext 1: 2: 3: 4:
| procedure TForm1.Button3Click(Sender: TObject); begin ShowMessage(IntToStr(CompareImages(Image1.Picture.Bitmap,Image2.Picture.Bitmap))); end; |
Vielen Dank!
|
|
Gausi
      
Beiträge: 8548
Erhaltene Danke: 477
Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
|
Verfasst: Do 23.09.10 13:42
Wie liegen die Bitmaps denn vor? In Dateien? Dann könnte man das so machen:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| EinBild.LoadFromFile('c:\meinBild.bmp');
for i := 1 to 50 do begin NocheinBild.LoadFromFile('c:\NocheinBildNr' + IntTostr(i) + '.bmp'); Diff := CompareImages(EinBild, NocheinBild); ShowMessage(IntToStr(Diff)); end; |
_________________ We are, we were and will not be.
Für diesen Beitrag haben gedankt: HenryHux
|
|
HenryHux 
      
Beiträge: 542
Erhaltene Danke: 33
Windows 7 Premium
Delphi XE, Eclipse
|
Verfasst: Do 23.09.10 14:31
Ok, denke das könnte so klappen.
Habs jetzt so:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15:
| procedure TForm1.Button4Click(Sender: TObject); var i, diff : integer; EinBild, NocheinBild : TBitmap; begin EinBild.LoadFromFile('D:\image.bmp');
for i := 1 to 2 do begin NocheinBild.LoadFromFile('D:\image' + IntTostr(i) + '.bmp'); Diff := CompareImages(EinBild, NocheinBild); ShowMessage(IntToStr(Diff)); end; end; |
Wenn ichs starte stürtzt er ab mit der Fehlermeldung und zeigt mir EinBild.LoadFromFile('D:\image.bmp'); als Fehlerquelle.
Ne Idee?
---------------------------
Debugger Exception Notification
---------------------------
Project Project2.exe raised exception class EAccessViolation with message 'Access violation at address 0045890D in module 'Project2.exe'. Read of address 00000000'. Process stopped. Use Step or Run to continue.
---------------------------
OK Help
---------------------------
|
|
bummi
      
Beiträge: 1248
Erhaltene Danke: 187
XP - Server 2008R2
D2 - Delphi XE
|
Verfasst: Do 23.09.10 14:32
Wenn Du nicht BMP's mit JPG's vergeleichen muß wie wäre es mit:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76:
| unit Unit1;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs,Math, StdCtrls;
type TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private public end;
var Form1: TForm1;
implementation
{$R *.dfm} function CompareStreams(Stream1, Stream2: TStream): Extended; type TBuffer = array[0..8191] of Byte; const BuffSize = SizeOf(TBuffer); var Buffer1: TBuffer; Buffer2: TBuffer; BytesRead1: Integer; BytesRead2: Integer; DifferenceCount: Int64; Index: Integer; MaxCount: Integer; begin Stream1.Position := 0; Stream2.Position := 0; DifferenceCount := 0; while True do begin BytesRead1 := Stream1.Read(Buffer1, BuffSize); BytesRead2 := Stream2.Read(Buffer2, BuffSize); MaxCount := Min(BytesRead1, BytesRead2); for Index := 0 to MaxCount -1 do if Buffer1[Index] <> Buffer2[Index] then
Inc(DifferenceCount); if (BytesRead1 <> BytesRead2) or (BytesRead1 = 0) or (BytesRead2 = 0) then Break; end; Result := (DifferenceCount * 100) / Max(Stream1.Size, Stream2.Size); end;
procedure TForm1.Button1Click(Sender: TObject); var Stream1: TFileStream; Stream2: TFileStream; Differences: Extended; begin Differences := 0.0000; try Stream1 := TFileStream.Create('C:\temp\1.jpg', fmOpenRead); Stream2 := TFileStream.Create('C:\temp\1.1.jpg', fmOpenRead); Differences := CompareStreams(Stream1, Stream2); finally FreeAndNil(Stream1); FreeAndNil(Stream2); end; ShowMessageFmt('%.4f', [Differences]); end;
end. |
Für diesen Beitrag haben gedankt: HenryHux
|
|
Gausi
      
Beiträge: 8548
Erhaltene Danke: 477
Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
|
Verfasst: Do 23.09.10 14:36
Vorher müssen natürlich die Bitmap-Objekte einmal erzeugt werden:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7:
| EinBild := TBitmap.Create; NochEinBild := TBitmap.Create;
EinBild.Free; NochEinBild.Free; |
Zusätzlich noch Ressourcen-Schutzblöcke, also try...finally drumherum wie im Code von bummi bei den FileStreams. 
_________________ We are, we were and will not be.
Für diesen Beitrag haben gedankt: HenryHux
|
|
HenryHux 
      
Beiträge: 542
Erhaltene Danke: 33
Windows 7 Premium
Delphi XE, Eclipse
|
Verfasst: Do 23.09.10 14:49
Danke!
Hatte die Bilder im Bitmap Format. Aber Jpeg ist auch nicht schlecht zu wissen =)
Gausi hat folgendes geschrieben : | Vorher müssen natürlich die Bitmap-Objekte einmal erzeugt werden |  ..Natürlich. Danke!
Aber was ich nicht verstehe:
Zuerst vergleicht er ja das bmp mit bmp1. Die sind beide gleich, bis auf, dass das Zweite ein wenig mehr nach rechts verschoben ist. Das erkennt er gut und gibt mir als Wert 9967.
Dann vergleicht er bmp mit bmp2. Zwei völlig verschiedene Bilder. Er gibt mir 1000.
Dann bmp mit bmp3. Beide identisch und er gibt mir 0. Wieso? 0 dürfte hier doch nit exat gleich bedeuten?
Edit:
Ok 0 bedeutet 100%...
Eine kleine abschließenden Frage hätte ich aber noch.
Wie kann ich bei GetShoot2Image(image1,Rect(Breite,Hoehe,Breite + Breite2,Hoehe + Hoehe2),1); das Bild an sich kleiner machen?
|
|
Tilman
      
Beiträge: 1405
Erhaltene Danke: 51
Win 7, Android
Turbo Delphi, Eclipse
|
Verfasst: Do 23.09.10 16:24
Nur kurz zur Erklärung dieser Term: "(P1^<>P2^)", ergibt true wenn P1^ ungleich P2^ ist, und False wenn sie gleich sind. Das wird dann als Byte umgewandelt, true ist als Zahl "1" und False als Zahl "0". Wenn beide Pixel identisch sind, wird result also um 0 erhöht, sind beide verschieden wird Result um 1 erhöht. Vermutlich die schnellste Lösung, die aber dazu führt dass kein Anfänger den Code mehr begreift 
_________________ Bringe einen Menschen zum grübeln, dann kannst du heimlich seinen Reis essen.
(Koreanisches Sprichwort)
|
|
|