AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

zwei Bitmaps vergleichen

Offene Frage von "KahPee"
Ein Thema von KahPee · begonnen am 1. Feb 2010 · letzter Beitrag vom 2. Feb 2010
Antwort Antwort
Seite 1 von 3  1 23      
Benutzerbild von KahPee
KahPee

Registriert seit: 12. Mai 2009
214 Beiträge
 
Turbo Delphi für Win32
 
#1

zwei Bitmaps vergleichen

  Alt 1. Feb 2010, 13:00
Hallo,
ich hatte so eine ähnliche Frage schon mal gestellt, allerdings bin ich bei der Umsetzung damals gescheitert.
Ich habe vor zwei Bitmaps zu vergleichen.
Ich hatte bei meinem ersten Versuch vorallem Probleme mit den konvertieren und ähnlichem. Aber nochmal zu dem Problem:
1. Die beiden Bitmaps haben unterschiedliche größen (Bild1 ist sowohl in y als auch in x Richtung "größer gleich" Bild2)
2. Es soll geprüft werden ob Bild 2 an einer bestimmten Stelle von Bild1 ist
3. Ergebnis soll true/false sein

Im Prinzip stelle ich mir also so etwas vor:
Delphi-Quellcode:
function compareBitmaps(Bild1, Bild2: TBitmap; posx,posy: Integer):boolean;
  //Posx und Posy sollen angeben an welcher Stellen von Bild1 Bild2 verglichen werden wollen (obere linke Ecke)
var x,
    y,
    comparedpix, //Anzahl der verglichenen Pixel
    machtingpix: integer; //Anzahl der übereinstimmenden Pixel
   
begin
  Result:=false;

  for x:=0 to Bild2.width-1 do
  begin
    for y:=0 to Bild2.height-1 do
    begin
      if Bild1.Pixels[posx+x,posy+y]=Bild2.Pixels[x,y] then matchingpix:=matchingpix+1;
             //Problem: keine "Pixels" Option für Tbitmaps nur für TCanvas
      comparedpix:=comparedpix+1;
    end;
  end;
  
  if comparedpix=matchingpix then result:=true;

end
Ich hoffe obiger Sketch des Programmcodes kann einen Eindruck vermitteln was ich vor habe. Ich suche auch immer noch eine etwas schnellere Methode. Scanline fällt in diesem Fall weg (???) weil ich ja nur einen Auschnitt vergleichen will.

Wäre nett wenn mir jemand auf die Sprünge helfen könnte

mfg Kahpee
  Mit Zitat antworten Zitat
thepaine91

Registriert seit: 29. Okt 2009
Ort: Neckarsulm
36 Beiträge
 
Delphi 6 Enterprise
 
#2

Re: zwei Bitmaps vergleichen

  Alt 1. Feb 2010, 13:08
Nein Scanline ist genau richtig. Tipp: Schau dir mal das Return Value an.
Das Beispiel in der Delphi Hilfe zu Scanline kann dir auch weiterhelfen.
>>> Hier könnte eine Signatur stehen <<<
  Mit Zitat antworten Zitat
Benutzerbild von KahPee
KahPee

Registriert seit: 12. Mai 2009
214 Beiträge
 
Turbo Delphi für Win32
 
#3

Re: zwei Bitmaps vergleichen

  Alt 1. Feb 2010, 13:26
In meiner Hilfe (TurboDelphi "f1") sieht das seeehr mager aus.
Zitat:
Syntax
 property ScanLine: Pointer read GetScanline; Beschreibung
ScanLine wird nur bei DIBs (Device Independent Bitmaps) für Bildbearbeitungsprogramme verwendet, die Low-Level-Operationen auf Pixelebene durchführen.
Da komm ich nicht mit weiter.
Hast du vllt einen Link oder so? Auch ist mir noch nicht unklar wie ich bei ScanLine einen bestimmten Punkt in Bild1 angebe ab dem verglichen werden soll ...
  Mit Zitat antworten Zitat
thepaine91

Registriert seit: 29. Okt 2009
Ort: Neckarsulm
36 Beiträge
 
Delphi 6 Enterprise
 
#4

Re: zwei Bitmaps vergleichen

  Alt 1. Feb 2010, 13:33
Das zeigt mir Delphi als Beispiel. Hoffe das hilft dir weiter.

property ScanLine[Row: Integer]: Pointer;

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);

// Dieses Beispiel zeigt das direkte Zeichnen in das Bitmap
var
  x,y : Integer;
  BitMap : TBitMap;
  P : PByteArray;
begin
  BitMap := TBitMap.create;
  try
    BitMap.LoadFromFile('C:\Programme\Gemeinsame Dateien\Borland Shared\Images\Splash\256color\factory.bmp');
    for y := 0 to BitMap.Height -1 do
    begin
      P := BitMap.ScanLine[y];
      for x := 0 to BitMap.Width -1 do

        P[x] := y;
    end;
    Canvas.Draw(0,0,BitMap);
  finally
    BitMap.Free;
  end;
end;
>>> Hier könnte eine Signatur stehen <<<
  Mit Zitat antworten Zitat
Benutzerbild von KahPee
KahPee

Registriert seit: 12. Mai 2009
214 Beiträge
 
Turbo Delphi für Win32
 
#5

Re: zwei Bitmaps vergleichen

  Alt 1. Feb 2010, 13:41
ehm ja... Ich bin glaube ich zusehr Delphi Laie als das da zu sehen ...

wie ich die jeweils richtige Zeile auslese hab ich glaube ich schon kappiert:
  if Bild1.scanline[posy+y]=Bild2.Pixels[y] then matchingpix:=matchingpix+1; Allerdings wird in diesem Fall von Bild 1 die ganze Zeile gescannt. das will ich ja gar nicht . Ich möchte, dass ja nur ein bestimmter Teil des 1. Bildes gescannt wird. Wie krieg ich denn da jetzt eine Kontrolle über die gescannten und am Ende auch verglichenen Längen und Positionen der Zeilen?

mfg KahPee
  Mit Zitat antworten Zitat
thepaine91

Registriert seit: 29. Okt 2009
Ort: Neckarsulm
36 Beiträge
 
Delphi 6 Enterprise
 
#6

Re: zwei Bitmaps vergleichen

  Alt 1. Feb 2010, 13:50
Das ganze nochmal kommentiert.

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);

// Dieses Beispiel zeigt das direkte Zeichnen in das Bitmap
var
  x,y : Integer;
  BitMap : TBitMap;
  P : PByteArray;
begin
  BitMap := TBitMap.create;
  try
    BitMap.LoadFromFile('C:\Programme\Gemeinsame Dateien\Borland Shared\Images\Splash\256color\factory.bmp');
    for y := 0 to BitMap.Height -1 do
    begin
      P := BitMap.ScanLine[y]; // Füllt einen Array of Byte mit den Daten der angegebenen Zeile.
      for x := 0 to BitMap.Width -1 do
        // P = length Bitmap.width -1
// Wenn man jetzt row 1 ausliest und P unser Bytearray ist und dem zu folge P[1] ausliest hätte man das selbe wie Pixels[1,1]
        P[x] := y;
    end;
    Canvas.Draw(0,0,BitMap);
  finally
    BitMap.Free;
  end;
end;
Jetzt soweit verständlich
>>> Hier könnte eine Signatur stehen <<<
  Mit Zitat antworten Zitat
Benutzerbild von KahPee
KahPee

Registriert seit: 12. Mai 2009
214 Beiträge
 
Turbo Delphi für Win32
 
#7

Re: zwei Bitmaps vergleichen

  Alt 1. Feb 2010, 13:54
Oh.. Das war einfach VIELEN DANK!!

Noch eine ganz kurze Frage. Bei der aktuellen Prozedur wird in dem größeren Bild (Bild1) die ganze Zeil gescannt und anschließend wird nur an einer bestimmten Stelle verglichen. Kann man von vorneherein angeben, dass nur ein teil der Zeil gescannt werden soll um rechenzeit zu sparen?
Ich gehe mal davon aus, dass der array mit "0" anfängt

mdf Kahpee
  Mit Zitat antworten Zitat
Benutzerbild von Aphton
Aphton

Registriert seit: 31. Mai 2009
1.198 Beiträge
 
Turbo Delphi für Win32
 
#8

Re: zwei Bitmaps vergleichen

  Alt 1. Feb 2010, 14:13
Zitat von thepaine91:
Das ganze nochmal kommentiert.

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);

// Dieses Beispiel zeigt das direkte Zeichnen in das Bitmap
var
  x,y : Integer;
  BitMap : TBitMap;
  P : PByteArray;
begin
  BitMap := TBitMap.create;
  try
    BitMap.LoadFromFile('C:\Programme\Gemeinsame Dateien\Borland Shared\Images\Splash\256color\factory.bmp');
    for y := 0 to BitMap.Height -1 do
    begin
      P := BitMap.ScanLine[y]; // Füllt einen Array of Byte mit den Daten der angegebenen Zeile.
      for x := 0 to BitMap.Width -1 do
        // P = length Bitmap.width -1
// Wenn man jetzt row 1 ausliest und P unser Bytearray ist und dem zu folge P[1] ausliest hätte man das selbe wie Pixels[1,1]
        P[x] := y;
    end;
    Canvas.Draw(0,0,BitMap);
  finally
    BitMap.Free;
  end;
end;
Jetzt soweit verständlich
Das ganze nochmal verbessert

Du weißt schon, dass das so nicht korrekt ist?
Es gibt soetwas, dass nennt sich Pixelformat. Falls es beispielsweise auf pf24Bit gesetzt ist,
besteht das Bild (bzw dann die einzelnen Rows) aus aneinander gereihten 24/8 Bytes -> r, g, b; wobei die Reihenfolge nicht die gleiche sein muss...

Sieh dir das hier mal an:
Delphi-Quellcode:
var
  Pixel : PByte;
  y, k, x : Integer;
  bytes : Byte;
const
  PixelFormatBytes: Array[TPixelFormat] of Byte = ( 0, 0, 0, 1, 0, 2, 3, 4, 0 );
begin
  bytes := PixelFormatBytes[bmp.PixelFormat];
  if bytes = 0 then
    Exit; // PixelFormat wird nicht unterstützt ... kannst du dann gerne von mir aus umändern ...
  for y := 0 to bmp.Height - 1 do
  begin
    Pixel := bmp.Scanline[y];
    for x := 0 to bmp.Width - 1 do
      for k := 0 to bytes - 1 do
      begin
        Pixel^ := 0;
        inc( Pixel );
      end;
  end;
end;
das Erkennen beginnt, wenn der Erkennende vom zu Erkennenden Abstand nimmt
MfG
  Mit Zitat antworten Zitat
Benutzerbild von KahPee
KahPee

Registriert seit: 12. Mai 2009
214 Beiträge
 
Turbo Delphi für Win32
 
#9

Re: zwei Bitmaps vergleichen

  Alt 1. Feb 2010, 14:16
Delphi-Quellcode:
function Bitmapcompare(pic1, pic2: Tbitmap; Posx,posy: Integer): Boolean;
var line1,line2: Pbytearray;
    x,y: integer;
    compix, matchpix: integer;
begin
  Result:=false;
  matchpix:=0;
  compix:=0;

  for y := 0 to pic2.Height - 1 do
  begin
    line1:=pic1.ScanLine[posy+y];
    line2:=pic2.ScanLine[y];
    for x := 0 to pic2.width - 1 do
      begin
        if line1[posx+x]=line2[x] then matchpix:=matchpix+1;
        compix:=compix+1;
      end;
  end;

  if compix=matchpix then Result:=true;

end;
Der Code macht seine Sache gut . Vielen Dank habs grad ausprobiert und der erste Test verlief erfolgreich

mfg KahPee
  Mit Zitat antworten Zitat
thepaine91

Registriert seit: 29. Okt 2009
Ort: Neckarsulm
36 Beiträge
 
Delphi 6 Enterprise
 
#10

Re: zwei Bitmaps vergleichen

  Alt 1. Feb 2010, 14:20
Nein weis ich nicht weil ich mich noch nie mit TBitmap befasst hatte vorher ich hab nur 2 min die Hilfe durchgeguckt ob ich was finde.
Und da habe ich das wohl übersehen.
>>> Hier könnte eine Signatur stehen <<<
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 3  1 23      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:51 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