Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Bilder vergleichen -> optimiertes verfahren gesucht! (https://www.delphipraxis.net/49829-bilder-vergleichen-optimiertes-verfahren-gesucht.html)

alleinherrscher 16. Jul 2005 18:54


Bilder vergleichen -> optimiertes verfahren gesucht!
 
Hi, hab dieses Forum schon durchsucht, allerdings keinen wirklich passenden Thread gefunden. Einfaches Problem: Ich lade zwei gleich große bilder in eine canvas, und vergleiche Sie. Der unterschied (nur das Rechteck zwischen kleinsten unterschiedlichem Punkt und größtem unterschiedlichen punkt) wird in bild3 gespeichert. Allerdings braucht mein Rechner dafür ca. 10 sekunden, was mir zu lange ist. Gibts ne möglichkeit, diesenm Code zu optimieren?

Delphi-Quellcode:
var
  c   : TCanvas;
  r,r2    : TRect;
  Bild,Bild2,bild3 : TBitmap;
  x,y,x_min,y_min,x_max,y_max:integer;
begin
 x_min:=9999999;
 y_min:=9999999;
 x_max:=0;
 y_max:=0;

    Bild       := TBitmap.Create;
    Bild2       :=TBitmap.Create;

    Bild.LoadFromFile('C:\windows\desktop\bild1.bmp');
    Bild2.LoadFromFile('C:\windows\desktop\bild2.bmp');

    for x:=1 to bild.width do
    for y:=1 to bild.height do
     begin
       if bild.Canvas.pixels[x,y]<>bild2.Canvas.pixels[x,y] then
       begin
       if x_min>x then x_min:=x;
       if x_max<x then x_max:=x;
       if y_min>y then y_min:=y;
       if y_max<y then y_max:=y;

       end;
     end;
    r := Rect(0, 0, x_max-x_min, y_max-y_min);
    r2:= rect(x_min,y_min,x_max,y_max);
    Bild3:=TBitmap.Create;
    bild3.Width:=x_max-x_min;
    bild3.height:=y_max-y_min;
    bild3.Canvas.CopyRect(r,bild2.canvas,r2);
    bild3.SaveToFile('C:\windows\desktop\bild3.bmp');
     showmessage('fertig');
  end;
Mit freundlichen Grüßen,

Alleinherrscher

Ultimator 16. Jul 2005 18:56

Re: Bilder vergleichen -> optimiertes verfahren gesucht!
 
Der Canvas.Pixels-Zugriff ist enorm langsam, du solltest besser Hier im Forum suchenscanLine Delphi-Referenz durchsuchenScanLine verwenden.
Alternativ auch die Hier im Forum suchengr32-Library, die ist wesentlich schneller und überhaupt wurde dort viel optimiert im Gegensatz zu den Bitmap- und Image-Komponenten, die Delphi standardmäßig mitbringt ;)

//Ach ja, Ressourcenschutzblöcke nicht vergessen, die Bitmaps wollen ja auch wieder freigegeben wreden ;)

bigg 16. Jul 2005 19:08

Re: Bilder vergleichen -> optimiertes verfahren gesucht!
 
:hi:

Beide Bilder müssen gleich sein?
Dann kontrolliere zunächst folgende Größen:

- Dateigröße
- Hohe und Breite
- Farbpalette

Sind diese gleich, kannst du die Dateien mit der Klasse "TFileStream" einlesen
und vergleichen.

Mit Scanline geht das natürlich auch, dies könnte jedoch bei größeren Dateien
zum Performance-Killer werden.

Jan 16. Jul 2005 19:09

Re: Bilder vergleichen -> optimiertes verfahren gesucht!
 
Nicht nur, das was vorher erwähnt wurde kannst du verbessern, sondern auch deinen Algo, der meiner Meinung nach ziemlich viel unnütze Berechnung anstellt.


Delphi-Quellcode:
var
  c   : TCanvas;
  r,r2    : TRect;
  Bild,Bild2,bild3 : TBitmap;
  x,y,x_min,y_min,x_max,y_max:integer;
begin
x_min:=9999999;
y_min:=9999999;
x_max:=0;
y_max:=0;

    Bild       := TBitmap.Create;
    Bild2       :=TBitmap.Create;

    Bild.LoadFromFile('C:\windows\desktop\bild1.bmp');
    Bild2.LoadFromFile('C:\windows\desktop\bild2.bmp');

    for x:=1 to bild.width do
    for y:=1 to bild.height do
     begin
       if bild.Canvas.pixels[x,y]<>bild2.Canvas.pixels[x,y] then
       begin
bis dahin war in Ordnung.
aber dann würde ich folgendes schreiben:


Delphi-Quellcode:
        x_min:=x;
        y_min:=y;
        break;
      end;
    end;
    for x:=bild.width downto 1 do
    for y:=bild.height downto 1 do    
    begin
      if bild.Canvas.pixels[x,y]<>bild2.Canvas.pixels[x,y] then
      begin
        x_max:=x;
        y_max:=y;
        break;
      end;
    end;
    r2:= rect(x_min,y_min,x_max,y_max);
    Bild3:=TBitmap.Create;
    bild3.Width:=x_max-x_min;
    bild3.height:=y_max-y_min;
    bild3.Canvas.CopyRect(r,bild2.canvas,r2);
    bild3.SaveToFile('C:\windows\desktop\bild3.bmp');
    showmessage('fertig');
  end;
Probier das mal! Ist aber alles ungetestet und so ins textfester eingetippt, also keine Garantie.
Gruß

alleinherrscher 16. Jul 2005 19:10

Re: Bilder vergleichen -> optimiertes verfahren gesucht!
 
danke für die super schnelle antwort, werde jetzt die g32 lib testen! thx!!!!

Khabarakh 16. Jul 2005 19:15

Re: Bilder vergleichen -> optimiertes verfahren gesucht!
 
Delphi-Quellcode:
for x:=1 to bild.width do
for y:=1 to bild.height do
Das sollte so aussehen:
Delphi-Quellcode:
for x := 0 to Bild.Width - 1 do
  for y := 0 to Bild.Height - 1 do
Außerdem darfst du nicht vergessen, die Bitmaps wieder freizugeben.

Ansonsten schließe ich mich Ultimator voll und ganz an.

@bigg:
Gute Idee, alleinherrscher will aber die Unterschiede auch abspeichern :wink: .

bigg 16. Jul 2005 19:33

Re: Bilder vergleichen -> optimiertes verfahren gesucht!
 
Zitat:

Zitat von Khabarakh
@bigg:
Gute Idee, alleinherrscher will aber die Unterschiede auch abspeichern :wink: .

Und das ist deiner Meinung mit TFileStream nicht möglich, falsch!

@Autor:
Wenn du auf das Bild malst per Canvas, muss das Bild immer wieder neu gezeichnet werden
und das kostet Zeit.

alleinherrscher 16. Jul 2005 20:55

Re: Bilder vergleichen -> optimiertes verfahren gesucht!
 
Hi@all!

Also erstmal danke für die ganzen antworten!

@Jan: Ich verstehe nicht, warum deine Routine schneller gehen soll...du geht doch per pixels anweisung das ganzen Bild 2 mal durch, dadurch müsste es doch auch im endeffekt doppeltsolange dauern.

Ich benutzte nun die g32 lib. die funktion ist super, dauert inetwa noch so 3 sekunden, allerdings folgendes problem: Es wird nicht mehr der richtige bildausschnitt kopiert, weil aus einen mir unbekannten grund x_max und y_max nicht mehr korrekt erkannt werden (achtet auf meine kommentierung im Source Code!)

Delphi-Quellcode:
var
  r,r2    : TRect;
  Bild,Bild2,bild3 : TBitmap32;
  x,y,x_min,y_min,x_max,y_max:integer;
begin
 x_min:=9999999;
 y_min:=9999999;
 x_max:=0;
 y_max:=0;

    Bild       := TBitmap32.Create;
    Bild2       :=TBitmap32.Create;
        Bild3:=TBitmap32.Create;
    Bild.LoadFromFile('C:\windows\desktop\bild1.bmp');
    Bild2.LoadFromFile('C:\windows\desktop\bild2.bmp');

    for x:=0 to bild.width-1 do
    for y:=0 to bild.height-1 do
     begin
       if bild[x,y] <> bild2[x,y] then
       begin

       if x_min>x then x_min:=x;
       if x_max<x then x_max:=x;
       if y_min>y then y_min:=y;
       if y_max<y then y_max:=y;

       end;
     end;
    showmessage(inttostr(x_min)+' '+inttostr(y_min)+' '+inttostr(x_max)+' '+inttostr(y_max));

    r := Rect(0, 0, x_max, y_max);
    r2:= rect(x_min,y_min,x_max-x_min,y_max-y_min);

    bild3.Width:=x_max-x_min;
    bild3.height:=y_max-y_min;
    bild2.drawto(bild3,r2,r); //hier das verstehe ich gar nicht, denn:
//wenn ich r und r2 vertausche, werden x_max und y_max wieder richtig
//erkannt. kann mir das jemand erklären?!? Ist das n fehler in der g32
//lib? 



    bild3.SaveToFile('C:\windows\desktop\bild3.bmp');
     showmessage('fertig');
  end;
Ich will ja nicht nerven, aber kann mir da jemand helfen?

Khabarakh 16. Jul 2005 22:25

Re: Bilder vergleichen -> optimiertes verfahren gesucht!
 
Zitat:

Zitat von bigg
Zitat:

Zitat von Khabarakh
@bigg:
Gute Idee, alleinherrscher will aber die Unterschiede auch abspeichern :wink: .

Und das ist deiner Meinung mit TFileStream nicht möglich, falsch!

Es ist sicher möglich, CopyRect/BlockTransfer für einen Stream nachzubauen, aber da nehme ich doch lieber die fertigen Lösungen :wink: .
Zitat:

Zitat von bigg
@Autor:
Wenn du auf das Bild malst per Canvas, muss das Bild immer wieder neu gezeichnet werden
und das kostet Zeit.

Aber doch nicht bei einem Bitmap im Speicher.

@alleinherrscher:
Was meinst du mit "erkannt" :gruebel: ?

alleinherrscher 16. Jul 2005 22:49

Re: Bilder vergleichen -> optimiertes verfahren gesucht!
 
Folgendes: Ich habe einen Screenshot von meinem Desktop gemacht, abgespeichert als Bild1.bmp
Dann habe ich in dieses Bild mit Paint ein weißes rechteck "reingemalt" und das als Bild2.bmp abgespeichert.

Wenn ich die Delphi-routine benutzte, also mit bild.canvas.pixels[x,y] arbeite, um den unterschied zwischen beiden Bildern herauszufinden, so wird in Bild3.bmp genau mein manipuliertes weißes rechteck abgespeichert.
Benutzte ich aber bild[x,y] oder bild.pixel[x,y], also die g32 komponenten, so wird in Bild3 mehr gepspeichert, als das weiße rechteck. Man kann noch teile vom Desktop sehen. Ich habe dann in einer Messagebox die x_min...usw koordinaten angeben lassen. Mit g32 ergeben sich andere und daher auch leider falsche werte für x_min,x_max,y_min, und y_max, als mit der Delphi Funktion.

Ich frage mich, warum?!

Jan 17. Jul 2005 00:12

Re: Bilder vergleichen -> optimiertes verfahren gesucht!
 
Zitat:

Zitat von alleinherrscher
Hi@all!
@Jan: Ich verstehe nicht, warum deine Routine schneller gehen soll...du geht doch per pixels anweisung das ganzen Bild 2 mal durch, dadurch müsste es doch auch im endeffekt doppeltsolange dauern.

Das ist so nicht richtig. das ganze ist aus 2 Gründen theoretisch schneller.
1. Du checkst für JEDEN Pixel im bild ob er kleiner als das bisherige minimum ist und ob er größer ist als das bisherige maximum.
Das ganze habe ich verkürz, indem ich einfach nur den vergleich auf unterschied mache.
undzwar einmal von unten, und den ersten Wert der unterschiedlich ist auf Minimum setze. Danach wird die Schleife abgebrochen. Schlimmstenfalls geht er das ganze Bild durch, aber bestenfalls findet er den Unterschied schon beim ersten Pixel und spart sich jede Menge Laufzeit, außerdem habe ich die ganzen Vergleiche rausgeschmissen weil man die nicht braucht.
Das ganze mache ich dann noch fürs maximum, allerdings dann von oben, weil ich mal denke, dass es wahrscheinlicher ist, dass der Punkt im unteren Bildbereich ist. Somit spart man sich im mittel jede Menge Laufzeit.
Wenn du das ausprobierst kannste ja mal vergleichen.
Gruß
Jan

alleinherrscher 17. Jul 2005 12:37

Re: Bilder vergleichen -> optimiertes verfahren gesucht!
 
@Jan: Ok, das sehe ich ein. Aber mein Problem ist ja, dass das ganze durch die canvas.pixels[x,y] routine verlangsamt wird, weil die - delphiintern nunmal eine sehr lange zugriffszeit auf das einzelne Pixel hat. Die Pixels[x,y] Funktion ist also der Flaschenhals. Und korrigiere mich, wenn ich falsch liege, du gehst mit der Pixels Funktion ALLE Pixel exakt 2 mal durch, meine Routine aber nur einmal. Sie wird mit sicherheit durch die umständliche if abfrage verlangamt, keine Frage. Aber müsste im Vergleich zu deiner Funktion immernoch schneller sein, weil die nur einmal jedes Pixel abfragt.

@all: Das alle löst leider immernoch nicht mein Problem...Kann es sein, dass die g32 Library da einen Fehler hat? (siehe meine vorherigen Einträge)...ich bekomme exakt das selbe Programm nicht mehr richtig zum laufen, wenn ich canvas.pixels[x,y] durch image32[x,y] ersetzte. Es geht zwar ca. 5 mal schneller, aber arbeit unkorrekt (siehe oben)

Edit: Mir ist gerade aufgefallen, dass es mit g32 "ab und zu" richtig arbeitet. D.h. wenn ich z.B. das erste mal vergleiche, wird das weiße Rechteck richtig erkannt, wenn ich nochmal Klicke, wird zu viel erkannt, wenn ich nochmal klicke wirds wieder richtig erkannt...aber völlig unsystematisch...dh. ich weiß beim nächsten klick nicht, ob es richtig oder falsch erkannt wird....

Hat da jemand einen Rat? Ich bin nämlich ziemlich Ratlos... :wall:

Gruß, Alleinherrscher

alleinherrscher 17. Jul 2005 13:09

Re: Bilder vergleichen -> optimiertes verfahren gesucht!
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hier, hab das Programm mal angehängt. Probiers mal aus. Also wie gesagt, habe bei mir 2 Screenshots mit "PrintScreen"-Taste gemacht, dann in Paint als 24Bit BMP abgespeichert, dann ein weißes Feld gemacht und erneut als anderes 24bit bmp abgespeichert. Manchmal erkennt das Programm das weiße Feld korrekt, manchmal werden aber unterschiede erkannt, obwohl es keine unterschiede gibt...tritt das bei euch auch auf? ruhig 10-20mal testen bitte!

Gruß, Alleinherrscher

Ultimator 17. Jul 2005 13:18

Re: Bilder vergleichen -> optimiertes verfahren gesucht!
 
Zitat:

Zitat von alleinherrscher
Kann es sein, dass die g32 Library da einen Fehler hat? (siehe meine vorherigen Einträge)...ich bekomme exakt das selbe Programm nicht mehr richtig zum laufen, wenn ich canvas.pixels[x,y] durch image32[x,y] ersetzte. Es geht zwar ca. 5 mal schneller, aber arbeit unkorrekt (siehe oben)

Und wenn du
Delphi-Quellcode:
image321.Bitmap.PixelS[x,y]
versuchst?

scp 17. Jul 2005 13:19

Re: Bilder vergleichen -> optimiertes verfahren gesucht!
 
Zitat:

Zitat von alleinherrscher
@Jan: Ok, das sehe ich ein. Aber mein Problem ist ja, dass das ganze durch die canvas.pixels[x,y] routine verlangsamt wird, weil die - delphiintern nunmal eine sehr lange zugriffszeit auf das einzelne Pixel hat. Die Pixels[x,y] Funktion ist also der Flaschenhals. Und korrigiere mich, wenn ich falsch liege, du gehst mit der Pixels Funktion ALLE Pixel exakt 2 mal durch, meine Routine aber nur einmal. Sie wird mit sicherheit durch die umständliche if abfrage verlangamt, keine Frage. Aber müsste im Vergleich zu deiner Funktion immernoch schneller sein, weil die nur einmal jedes Pixel abfragt.

Nein, er geht das ganze Bild nicht zweimal durch, es wird ja direkt unterbrochen, sobald das erste unterschiedliche Pixel gefunden ist. Probiers doch einfach aus.
Du kannst das ganze von Jan auch auf g32 übertragen, dann ist es min. 3-4x so schnell.

Khabarakh 17. Jul 2005 13:34

Re: Bilder vergleichen -> optimiertes verfahren gesucht!
 
Zitat:

Zitat von Ultimator
Zitat:

Zitat von alleinherrscher
Kann es sein, dass die g32 Library da einen Fehler hat? (siehe meine vorherigen Einträge)...ich bekomme exakt das selbe Programm nicht mehr richtig zum laufen, wenn ich canvas.pixels[x,y] durch image32[x,y] ersetzte. Es geht zwar ca. 5 mal schneller, aber arbeit unkorrekt (siehe oben)

Und wenn du
Delphi-Quellcode:
image321.Bitmap.PixelS[x,y]
versuchst?

Es würde mich wundern, wenn man mit
Delphi-Quellcode:
for x:=0 to bild.width-1 do
    for y:=0 to bild.height-1 do
     begin
       if bild[x,y] <> bild2[x,y] then
außerhalb des Bitmaps kommt :wink: .

bigg 17. Jul 2005 13:56

Re: Bilder vergleichen -> optimiertes verfahren gesucht!
 
Zitat:

Aber doch nicht bei einem Bitmap im Speicher.
Wenn es angezeigt wird, schon,
aber das ist in diesem Fall nicht der springende Punkt.

alleinherrscher 17. Jul 2005 14:03

Re: Bilder vergleichen -> optimiertes verfahren gesucht!
 
Ok, ich hatte das Break überlesen, Jan hat recht, sorry! Ich werde natürlich die Routine benutzten, die ist dann echt klasse.. :P tut mir leid...

scp 17. Jul 2005 14:11

Re: Bilder vergleichen -> optimiertes verfahren gesucht!
 
Ich habs grad mal getestet:
- Bei Jans Variante fehlt nur noch das zweite Break, für die zweite Schleife
- Der Ziel-Rect (r) ist nicht definiert, ein Wunder das es bis jetzt geklappt hat, deswegen dürfteauch g32 ins schleudern gekommen sein.
- Bei bild3 sollte PixelFormat definiert werden, bei mir kam sonst EOutOfResources und die Höhe/Breite mit +1
Delphi-Quellcode:
      bild3.PixelFormat := bild.PixelFormat;
      bild3.Width := x_max-x_min+1;
      bild3.height := y_max-y_min+1;
      r := rect(0, 0, bild3.Width, bild3.height);
- Und zum Schluss: try .. finally nicht vergessen.

PS: Jans Variante hat bei mir mit dem einfachen Rechteck-Paint-Beispiel nur 250 msec gebraucht!

alleinherrscher 17. Jul 2005 14:49

Re: Bilder vergleichen -> optimiertes verfahren gesucht!
 
Liste der Anhänge anzeigen (Anzahl: 1)
Also ich hab jetzt Jans Idee verwendet, ist zwar bei meiner alten Kiste nicht viel schneller (immernoch so 2 Sekunden) aber ich sehe ein, dass das die beste Lösung ist für das Problem ;-) Danke@Jan und die anderen!

Aber: *g* Das alte Problem besteht weiter, schaut mal hier. Ich habe zwei Bilder angehängt, die das Programm als Bild3.bmp ausgibt. Es werden von der g32 Lib Pixel mit gleichen Farbwerten als unterschiedlich erkannt.

Das einzige was ich noch nicht gemacht hab ist das "PixelFormat" eingestellt (das kann aber nicht der fehler sein, es gibt kein Pixelformat im TBitmap32)

Gruß, Alleinherrscher

scp 17. Jul 2005 16:44

Re: Bilder vergleichen -> optimiertes verfahren gesucht!
 
Bei Bitmap32 gehts ohne PixelFormat (oder vergleichbares). Kann dein Problem allerdings nicht nachvollziehen, wenn man reine Bitmaps verwendet.
Ist die ursprüngliche Quelle allerdings ein JPEG z.B., dann musst du den Vergleich etwas Fehlertoleranter gestalten, da hier die Farben von der Kompression verfälscht werden.

Statt bild.Canvas.pixels[x,y]<>bild2.Canvas.pixels[x,y] solltest du eine Vergleichs-Funktion basteln, z.B.:
Delphi-Quellcode:
// Liefert true zurück, wenn Pixel unterschiedlich.
function PixelCompare(A, B: DWORD): boolean;
begin
  result := (Abs(RGBQuad(A).rgbBlue - RGBQuad(B).rgbBlue ) +
             Abs(RGBQuad(A).rgbGreen - RGBQuad(B).rgbGreen) +
             Abs(RGBQuad(A).rgbRed  - RGBQuad(B).rgbRed ) ) > 64;
end;
Angewendet wird sie dann so:
Delphi-Quellcode:
        if PixelCompare(bild.Canvas.pixels[x,y], bild2.Canvas.pixels[x,y]) then
Diese Funktion lieferte nach ersten Tests gute Resultate, ist aber nicht "wissenschaftlich untermauert". :-)

alleinherrscher 17. Jul 2005 16:58

Re: Bilder vergleichen -> optimiertes verfahren gesucht!
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hi Scp!

Ich weiß auch, dass jpgs ne ungenauigkeit beim komprimieren bekommen. Hier hab ich ALLES (inkl. meiner Testbilder) mal gezippt...probierts mal aus. Es liefert oft das richtige ergebnis (genau den ausschnitt, der fehlerhaft ist) aber auch ab und zu einen zu großen oder falschen ausschnitt...

Danke für den Tipp mit dem JPG, aber könntest du dir das trotzdem mal anschauen, Scp? Das wäre lieb!

By the way: habe gerade deine Fehlertoleranz getestet, bei mir tritt trotzdem der selbe fehler auf, werde mir jetzt mal die farbwerte von dem als unterschiedlich erkannten pixeln ansehen...

scp 17. Jul 2005 17:08

Re: Bilder vergleichen -> optimiertes verfahren gesucht!
 
Sieht doch gut aus eigentlich nur
Delphi-Quellcode:
    r2:= rect(x_min,y_min,x_max+1,y_max+1);

    //bild3.PixelFormat := bild.PixelFormat;

    bild3.SetSize(x_max-x_min+1, y_max-y_min+1);
//    bild3.Width:=x_max-x_min+1;
//    bild3.height:=y_max-y_min+1;
bei r2 jeweils +1 (frag mich nicht warum) und nur der Form halber bei g32 SetSize() statt Width und Height verwenden. Außerdem fehlt immer noch try finally.

alleinherrscher 17. Jul 2005 17:24

Re: Bilder vergleichen -> optimiertes verfahren gesucht!
 
Ja, danke, aber das löst ja das Problem nicht...ich habe jetzt mal nachgeschaut:

Wenn das Programm den Fehler bei mir macht, also an der stelle [x,y] zwei unterschiedliche Pixel auf bild1 und bild2 erkennt, obwohl diese gleich sind und man für die stelle[x,y] die rgb werte ausgibt, geschieht folgendes:

Bild1: r:232g:219b:210(oder sonst was)
Bild2: r:232g:0 b:0

Allerseits an der Stelle x=664, y=21

Es gibt auch noch andere Fälle.
Da in diesem speziellen Fehlerfall der y wert der unteren grenze kleiner ist, als der der oberen Grenze, führt das ganze zu einem Fehler, da das bild3 theoretisch eine negative höhe hätte...

Erklär mir mal einer, warum die pixel funktion da z.B. an der stelle 664,21 mal unterschiede erkennt, aber mal wieder nicht?! Das kann eigentlich nicht an meinem Programm liegen...vielleicht liegts an D6 in kombination mit g32, was weiß ich...

Es scheint so, als ob in dem einen bild jeweils zwei farbwerte fehlen würden, tun sie aber nicht....*arg*

scp 17. Jul 2005 17:28

Re: Bilder vergleichen -> optimiertes verfahren gesucht!
 
Geschieht das denn bei den beigelegten Bildern? Also, under D2005 Personal gehts immer bis jetzt.

alleinherrscher 17. Jul 2005 17:36

Re: Bilder vergleichen -> optimiertes verfahren gesucht!
 
Liste der Anhänge anzeigen (Anzahl: 1)
Ja, genau bei denen! Ich kanns lad nochmal 2 beispiele hoch, wie bei mir bild3 aussieht...vielleicht sollte ich versuchen g32 neu zu installieren oder so was...

Benutze immoment folgende Version von g32:
Graphics32 v1.7.1 - Build on 25-Februar-2005

Jan 17. Jul 2005 18:41

Re: Bilder vergleichen -> optimiertes verfahren gesucht!
 
Vielen Dank @ scp fürs verteidigen meiner Routine!
Wenns wichtig ist das ganze würd ich mir einfach schnell den code zusammenbasteln zum auslesen eines Bitmaps und dem Auslesen der Farbwerte auf eigene Faust, ohne Kompo.
Gruß
Jan

scp 17. Jul 2005 20:55

Re: Bilder vergleichen -> optimiertes verfahren gesucht!
 
Liste der Anhänge anzeigen (Anzahl: 1)
Anbei das geänderte und unter D2005 kompilierte Projekt. Probier erst mal nur die .exe aus, brauchst nur die 2 bmps zurück in den Ordner kopieren.
Ich verwende auch die g32 1.71

@Jan
Namensvettern steht man eben zur Seite :-)

alleinherrscher 17. Jul 2005 21:53

Re: Bilder vergleichen -> optimiertes verfahren gesucht!
 
Danke für die ganze Mühe Scp! Es ist in der Tat wie ich vermutet habe...Deine Kompilation läuft ohne Probleme, 100 Prozentig inordnung (THX!!!), aber wenn ich das Projekt kompiliere, treten wieder die selben fehler auf. Scheinbar kann D6 nicht so gut mit gr32... i don't know...schade...mal schauen, was ich jetzt mache! :(

Danke erstmal! :hello:

scp 17. Jul 2005 22:49

Re: Bilder vergleichen -> optimiertes verfahren gesucht!
 
Naja, in dem Fall ist TBitmap bei mir genauso schnell, kannst ja erstmal das wieder nehmen.

turboPASCAL 18. Jul 2005 15:29

Re: Bilder vergleichen -> optimiertes verfahren gesucht!
 
Hi, Ihr's.

:gruebel: Habe mal ein Sample-Projekt erstellt das die Bitmaps mit Delphi-Referenz durchsuchenScanline vergleicht (ca. 33,3.14159 mal schneller als ...Pixel[x, y] ;-) ) also ohne gr32 Units. (Bild 5200 x 2600 auf einem AMD 2000 MHz ca. 0,5 Sekunden)

Original-Bild wird mit Test-Bild verglichen und die Unterschiede im Preview-Bild angezeigt.
Dieser Umstand deshalb, damit nicht die Vergleichs-Zeichnungen als Fehler interpretiert werden.

Mit ScanLine zu Arbeiten ist recht einfach z.B.:

Delphi-Quellcode:
procedure ScanLine_PutPixel(Bitmap: TBitmap; X, Y: Integer; Color: TColor);
var
  Pixel: PRGBQuad;
begin
  Pixel := Bitmap.ScanLine[Y];
  Inc(Pixel, X);

  Pixel^.rgbRed := Byte(Color);
  Pixel^.rgbGreen := Byte(Color shr 8);
  Pixel^.rgbBlue := Byte(Color shr 16);
end;
Link verschoben nach: Bitmap Compare - Bitmaps vergleichen mit Scanline (wegen der Möglichkeit der Bearbeitung)

DGL-luke 18. Jul 2005 15:36

Re: Bilder vergleichen -> optimiertes verfahren gesucht!
 
wieso zur hölle is da ne debugger detection drin?!

macht ja in einem sourcecode-beispiel herzlich wenig sinn...

und ausserdem krieg ich immer gesagt "bilder sind gleich"...

EDIT: und vor allem wieso kann ich von der debugger detection nix im qt finden? hab ich da etwa einen trojaner aufgeschnappt? :pale:

turboPASCAL 18. Jul 2005 16:02

Re: Bilder vergleichen -> optimiertes verfahren gesucht!
 
:gruebel: ne' Debugger Detection ? Sowas benutze ich doch niemals nicht. :zwinker:

Hast Du auch zwei unterschiedliche Bilder geladen (mit "Pixelfehlern") ? Nicht JPEG !

(nochmal nachgeschaut und hochgeladen)

//Edit: Da war noch die Unit JPEG dabei, was nicht sein sollte.

sniper_w 18. Jul 2005 16:03

Re: Bilder vergleichen -> optimiertes verfahren gesucht!
 
Zitat:

und vor allem wieso kann ich von der debugger detection nix im qt finden? hab ich da etwa einen trojaner aufgeschnappt?
Möglicherweise ;).
Also bei mir geht es wunderbar, und vorallem, schnell. Mal OT, aber Delphi ist doch ein RAD Tool. :)

scp 18. Jul 2005 17:24

Re: Bilder vergleichen -> optimiertes verfahren gesucht!
 
Respekt, nicht schlecht!
Hab mal zum Vergleich statt des roten Rechtecks einen Ausschnitt generiert, immernoch rasant:
Delphi-Quellcode:
var
//...
  bRect: TRect;
  MemBmp: TBitmap;

//...

    if RadioButton1.Checked then // Rotes Rechteck war hier, jetzt Ausschnitt :-)
    begin
      Inc(aRect.Right);
      Inc(aRect.Bottom);

      MemBmp := TBitmap.Create;
      try
        MemBmp.PixelFormat := PrevImage.Picture.Bitmap.PixelFormat;
        MemBmp.Width := aRect.Right - aRect.Left;
        MemBmp.Height := aRect.Bottom - aRect.Top ;

        bRect := Rect(0, 0, MemBmp.Width, MemBmp.Height);
        MemBmp.Canvas.CopyRect(bRect, PrevImage.Picture.Bitmap.Canvas, aRect);

        PrevImage.Picture.Bitmap.Assign(MemBmp);
      finally
        MemBmp.Free;
      end;
    end;

turboPASCAL 18. Jul 2005 17:40

Re: Bilder vergleichen -> optimiertes verfahren gesucht!
 
@scp Feine Sache, baue ich schnell mal noch mit ein.

[Begin OT] Und wenn man das ganze noch mit Bilder von 'ner WebCam macht, hat man ein prima Bewegungsmelder mit "Autofocus" ! [End OT]

sniper_w 18. Jul 2005 17:44

Re: Bilder vergleichen -> optimiertes verfahren gesucht!
 
Zitat:

Und wenn man das ganze noch mit Bilder von 'ner WebCam macht, hat man ein prima Bewegungsmelder mit "Autofocus" !
Für so etwas braucht man nicht extra Software. Wenn ich mich nicht irre, sollte man den WebCam-Processor reprogrammieren können, so ist das Ganze mit der Hardware Beschleunigung.

turboPASCAL 18. Jul 2005 18:15

Re: Bilder vergleichen -> optimiertes verfahren gesucht!
 
Hier gibt es keinen [SLP] Knopf, sonst hätte ich ihn noch vorangestellt. :zwinker:

SLP = Slapstick b.z.w. Sinnlos

sniper_w 18. Jul 2005 18:21

Re: Bilder vergleichen -> optimiertes verfahren gesucht!
 
Zitat:

Hier gibt es keinen [SLP] Knopf, sonst hätte ich ihn noch vorangestellt.
Heißt das, daß ch aus dem Bauch gesprochen habe ? :stupid: :mrgreen:

dizzy 18. Jul 2005 18:48

Re: Bilder vergleichen -> optimiertes verfahren gesucht!
 
Liste der Anhänge anzeigen (Anzahl: 1)
Ich habe jetzt nicht geprüft ob das in der Version weiter oben schon bedacht wurde, aber die ersten Sources dürften Probleme mit nicht rechteckigen Bereichen haben, insbesondere mit Kreisen.
Grund: Der Top-Pixel wird richtig erkannt, aber der damit verbundene Left-Pixel ist ja nicht zwangsläufig der "linkeste". Analog für Bottom/Right.

Hier mal eine Variante mit der G32. Sie sollte recht fix sein, und o.g. mit abdecken.

Ich hatte zuvor eine Optimierung probiert, indem ich zunächst zu den beiden Ausgangsbildern ein Differenzbild gebildet habe, und in diesem nach nicht schwarzen Pixeln gesucht. Hintergedanke war, dass ein Vergleich auf 0 (=schwarz) schneller ist als ein tatsächlicher Vergleich. Jedoch ist die Differenzbildung an sich deutlich zu aufwändig, was diese Optimierung eher unbrauchbar macht :stupid:

(Anmerkung: Die beiden zu vergleichenden Bilder werden als gleich groß vorausgesetzt! Es findet keine Prüfung statt, so dass es dann zu einer AV kommen sollte ;))

\\edit: Das Verfahren ist umso schneller, je größer der unterschiedliche Bereich ist. Nur so nebenbei :).
Nochwas: Will man NUR die wirklich veränderten Pixel darstellen, und die gleichen die auch innerhalb des Rechtecks liegen hingegen schwarz (oder andersfarbig), so kann man zusätzlich nachher die entsprechenden Pixel der Ausgangsbilder vergleichen, und bei gleichheit den Pixel im Ausgangsbild umfärben. Dann bekommt man das kleinste Rechteck der Änderungen, indem nur Pixel nicht-schwarz sind die tatsächlich verändert sind.


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:52 Uhr.
Seite 1 von 2  1 2      

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