Grafik pixelweise vergleichen

Anfängerfragen zum Programmieren mit PureBasic.
torstenh
Beiträge: 24
Registriert: 16.10.2010 21:37

Grafik pixelweise vergleichen

Beitrag von torstenh »

Hallo zusammen,

ich möchte gern zwei .bmp Dateien pixelweise vergleichen. Habe es mit "fingerprint" probiert aber hier kann ich kein Range einstellen. Das heißt das ich die Genauigkeit einstellen möchte.
Es werden immer nur zwei Bilder verglichen. Kann mir jemand auf die Sprünge helfen? ich benutze PUREBASIC 4.00. Habe im Forum einige Threads gelesen, mit for/next Schleife usw aber ich habe keinen Ansatz.
Ein Link würde mir genügen z.B. welche Befehle ich nehmen könnte um z.B. den gleichen Bereich zweier Bilder zu vergleichen.


Danke euch!

Grüße,
Torsten
Benutzeravatar
RSBasic
Admin
Beiträge: 8047
Registriert: 05.10.2006 18:55
Wohnort: Gernsbach
Kontaktdaten:

Re: Grafik pixelweise vergleichen

Beitrag von RSBasic »

Wenn du wirklich zwei Bilder pixelweise vergleichen möchtest, dann erstell zwei Zählschleifen (For To Next) für y und x und ermittel für jede Position des Pixels mit Point().
Hoffe, es hilft dir weiter.

\\Edit:
Also etwa so, aber dieser Code kann man bestimmt optimieren, habs einfach mal rasch so geschrieben:

Code: Alles auswählen

EnableExplicit

Define y
Define x
Define width=4
Define height=4
Define color1
Define color2

CreateImage(1,width,height,32)
CreateImage(2,width,height,32)

If StartDrawing(ImageOutput(1))
  Box(0,0,width,height,RGB(255,0,0))
  StopDrawing()
EndIf
If StartDrawing(ImageOutput(2))
  Box(0,0,width,height,RGB(255,0,0))
  Plot(1,2,RGB(255,255,255));1. Differenz
  Plot(2,3,RGB(255,255,255));2. Differenz
  StopDrawing()
EndIf

For y=0 To height-1
  For x=0 To width-1
    If StartDrawing(ImageOutput(1))
      color1 = Point(x,y)
      StopDrawing()
    EndIf
    If StartDrawing(ImageOutput(2))
      color2 = Point(x,y)
      StopDrawing()
    EndIf
    
    If color1<>color2
      Debug Str(x)+"x"+Str(y)
    EndIf
  Next x
Next y
Aus privaten Gründen habe ich leider nicht mehr so viel Zeit wie früher. Bitte habt Verständnis dafür.
Bild
Bild
Benutzeravatar
RSBasic
Admin
Beiträge: 8047
Registriert: 05.10.2006 18:55
Wohnort: Gernsbach
Kontaktdaten:

Re: Grafik pixelweise vergleichen

Beitrag von RSBasic »

Etwas optimiert, so dass es schneller beim Ermitteln ist:

Code: Alles auswählen

EnableExplicit

Define y
Define x
Define width=40
Define height=40
Define color1
Define color2

Dim Image1_Values(width-1,height-1)
Dim Image2_Values(width-1,height-1)

CreateImage(1,width,height,32)
CreateImage(2,width,height,32)

If StartDrawing(ImageOutput(1))
  Box(0,0,width,height,RGB(255,0,0))
  StopDrawing()
EndIf
If StartDrawing(ImageOutput(2))
  Box(0,0,width,height,RGB(255,0,0))
  Plot(1,2,RGB(255,255,255));1. Differenz
  Plot(2,3,RGB(255,255,255));2. Differenz
  Plot(4,4,RGB(255,255,255));3. Differenz
  StopDrawing()
EndIf

If StartDrawing(ImageOutput(1))
  For y=0 To height-1
    For x=0 To width-1
      Image1_Values(x,y) = Point(x,y)
    Next x
  Next y
  StopDrawing()
EndIf

If StartDrawing(ImageOutput(2))
  For y=0 To height-1
    For x=0 To width-1
      Image2_Values(x,y) = Point(x,y)
    Next x
  Next y
  StopDrawing()
EndIf

For y=0 To height-1
  For x=0 To width-1
    color1 = Image1_Values(x,y)
    color2 = Image2_Values(x,y)
   
    If color1<>color2
      Debug Str(x)+"x"+Str(y)
    EndIf
  Next x
Next y
Nun wird nicht bei jedem Durchlauf immer wieder StartDrawing() und StopDrawing() ausgeführt, sondern nur einmal am Anfang jeweils für jede Grafik und die Daten werden in ein Array gespeichert, so dass die Daten am Ende schnell verglichen werden können.
Aus privaten Gründen habe ich leider nicht mehr so viel Zeit wie früher. Bitte habt Verständnis dafür.
Bild
Bild
torstenh
Beiträge: 24
Registriert: 16.10.2010 21:37

Re: Grafik pixelweise vergleichen

Beitrag von torstenh »

oje! meine erste Danksagung kam nicht durch! Es hilft sicherlich um besser zu verstehen. Danke für deine Hilfe!!!!!
Da kann ich ein wenig rumprobieren.


Grüße,
Torsten
torstenh
Beiträge: 24
Registriert: 16.10.2010 21:37

Re: Grafik pixelweise vergleichen

Beitrag von torstenh »

:allright:

Super Sache Danke nochmals für die schnelle Antwort. Genau das habe ich gesucht, muss es noch an meine Bedürfnisse anpassen aber sonst super!


Grüße,
Torsten
Benutzeravatar
Regenduft
Beiträge: 574
Registriert: 25.03.2008 15:07
Wohnort: THE LÄÄÄND!

Re: Grafik pixelweise vergleichen

Beitrag von Regenduft »

Folgender Code ist gleichzeitig Antwort und Frage.

Antwort: Wenn Du Dich bereits mit Zeigern auskennst ist's so noch schneller.
Frage: Ist das zuverlässig? Die Adressen müssten ja eigentlich statisch sein...

Habe einfach mal grob den Code von RSBasic umgepflügt (und nur 32Bit-Grafiken beachtet).
Achtung: Ich habe kein DrawingBufferPitch() verwendet! Funktioniert also nur bei "Pitch = Breite*4"!

Code: Alles auswählen

EnableExplicit

Define x
Define y
Define width=40
Define height=40
Define x_max=width-1
Define y_max=height-1
Define *color1.Long
Define *color2.Long
Define reverse

CreateImage(1,width,height,32)
CreateImage(2,width,height,32)

If StartDrawing(ImageOutput(1))
  *color1 = DrawingBuffer()
  If DrawingBufferPixelFormat()|#PB_PixelFormat_ReversedY
    reverse=1
  EndIf
  Box(0,0,width,height,RGB(255,0,0))
  StopDrawing()
EndIf
If StartDrawing(ImageOutput(2))
  *color2 = DrawingBuffer()
  Box(0,0,width,height,RGB(255,0,0))
  Plot(1,2,RGB(255,255,255));1. Differenz
  Plot(2,3,RGB(255,255,255));2. Differenz
  Plot(4,4,RGB(255,255,255));3. Differenz
  StopDrawing()
EndIf

If reverse
  For y=0 To y_max
    For x=0 To x_max
      If *color1\l <> *color2\l
        Debug Str(x)+"x"+Str(y_max-y)
      EndIf
      *color1 + 4
      *color2 + 4
    Next x
  Next y
Else
  For y=0 To y_max
    For x=0 To x_max
      If *color1\l <> *color2\l
        Debug Str(x)+"x"+Str(y)
      EndIf
      *color1 + 4
      *color2 + 4
    Next x
  Next y
EndIf
Und ganz nebenbei an RSBasic: Ich hatte immer gedacht man solle in Zählschleifenköpfe keine Berechnungen reinbasteln, weil die bei jedem Durchlauf neu berechnet werden. Ist das falsch oder hast Du das nur aus "schnell mal zusammengeschrieben" Gründen so gemacht?
Zuletzt geändert von Regenduft am 07.11.2010 22:03, insgesamt 1-mal geändert.
PureBasic 5.73 LTE x86/x64 | Windows 7 (x64)
Benutzeravatar
RSBasic
Admin
Beiträge: 8047
Registriert: 05.10.2006 18:55
Wohnort: Gernsbach
Kontaktdaten:

Re: Grafik pixelweise vergleichen

Beitrag von RSBasic »

@Regenduft
Ich habs "schnell mal zusammengeschrieben".
Mit dem Buffer kann man allerdings auch machen, so spart man zwei Arrays.
Aus privaten Gründen habe ich leider nicht mehr so viel Zeit wie früher. Bitte habt Verständnis dafür.
Bild
Bild
Benutzeravatar
Thorium
Beiträge: 1722
Registriert: 12.06.2005 11:15
Wohnort: Germany
Kontaktdaten:

Re: Grafik pixelweise vergleichen

Beitrag von Thorium »

Regenduft hat geschrieben: Frage: Ist das zuverlässig? Die Adressen müssten ja eigentlich statisch sein...
Die Adressen sind schon statisch, zuverlässig ist dein Code trotzdem nicht, weil du den Pitch missachtest. Also wie lang eine Bildzeile im Speicher ist, die kann durchaus länger als Breite*4 sein. Aus Alignmentgründen kann die Breite z.B. immer durch 16 teilbar sein.
Zu mir kommen behinderte Delphine um mit mir zu schwimmen.

Wir fordern mehr Aufmerksamkeit für umfallende Reissäcke! Bild
c4s
Beiträge: 1235
Registriert: 19.09.2007 22:18

Re: Grafik pixelweise vergleichen

Beitrag von c4s »

Regenduft hat geschrieben:Und ganz nebenbei an RSBasic: Ich hatte immer gedacht man solle in Zählschleifenköpfe keine Berechnungen reinbasteln, weil die bei jedem Durchlauf neu berechnet werden. Ist das falsch oder hast Du das nur aus "schnell mal zusammengeschrieben" Gründen so gemacht?
Bemängelst du folgendes?

Code: Alles auswählen

  For y=0 To height-1
    For x=0 To width-1
Ich hatte nämlich komischerweise mal festgestellt, dass "height-1" im Schleifenkopf schneller ist als es bereits vorher abzuziehen.
Optimiert PureBasic da was? Sonst kann ich mir das nicht erklären...
"Menschenskinder, das Niveau dieses Forums singt schon wieder!" — GronkhLP ||| "ich hogffe ihr könnt den fehle endecken" — Marvin133 ||| "Ideoten gibts ..." — computerfreak ||| "Jup, danke. Gruss" — funkheld
Benutzeravatar
Regenduft
Beiträge: 574
Registriert: 25.03.2008 15:07
Wohnort: THE LÄÄÄND!

Re: Grafik pixelweise vergleichen

Beitrag von Regenduft »

Regenduft hat geschrieben:Habe einfach mal grob den Code von RSBasic umgepflügt (und nur 32Bit-Grafiken beachtet).
(...) Die Adressen müssten ja eigentlich statisch sein...
Thorium hat geschrieben:Die Adressen sind schon statisch, zuverlässig ist dein Code trotzdem nicht, weil du den Pitch missachtest. Also wie lang eine Bildzeile im Speicher ist, die kann durchaus länger als Breite*4 sein. Aus Alignmentgründen kann die Breite z.B. immer durch 16 teilbar sein.
Ich hatte den Pitch ignoriert, da ich dachte er wäre bei 32Bit Grafiken immer Breite*4.

Ich habe jetzt mal ein paar tausend Sprite- und Imagegrafiken (32 Bit) jeweils in verschiedensten Abmessungen (Random) erstellt und der Pitch war immer Breite*4 (WinXP x86).

Bist Du sicher, dass der Pitch auch mal z.B. 16 sein kann? Ist das Harware bedingt (Grafikkarte und/oder 32-/64-Bit Prozessor)?
c4s hat geschrieben:Ich hatte nämlich komischerweise mal festgestellt, dass "height-1" im Schleifenkopf schneller ist als es bereits vorher abzuziehen.
Optimiert PureBasic da was? Sonst kann ich mir das nicht erklären...
:? Das verwirrt mich jetzt aber sehr. Bei mir sind "vorberechnete Schleifenwerte" immer schneller.
PureBasic 5.73 LTE x86/x64 | Windows 7 (x64)
Antworten