Delphi-PRAXiS
Seite 1 von 5  1 23     Letzte »    

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?!


Alle Zeitangaben in WEZ +1. Es ist jetzt 21:16 Uhr.
Seite 1 von 5  1 23     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