Seite 1 von 2
Grafik pixelweise vergleichen
Verfasst: 01.11.2010 19:32
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
Re: Grafik pixelweise vergleichen
Verfasst: 01.11.2010 19:49
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
Re: Grafik pixelweise vergleichen
Verfasst: 01.11.2010 20:13
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.
Re: Grafik pixelweise vergleichen
Verfasst: 01.11.2010 21:22
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
Re: Grafik pixelweise vergleichen
Verfasst: 01.11.2010 22:36
von torstenh
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
Re: Grafik pixelweise vergleichen
Verfasst: 02.11.2010 14:11
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?
Re: Grafik pixelweise vergleichen
Verfasst: 02.11.2010 16:26
von RSBasic
@Regenduft
Ich habs "schnell mal zusammengeschrieben".
Mit dem Buffer kann man allerdings auch machen, so spart man zwei Arrays.
Re: Grafik pixelweise vergleichen
Verfasst: 03.11.2010 19:37
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.
Re: Grafik pixelweise vergleichen
Verfasst: 04.11.2010 00:23
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?
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...
Re: Grafik pixelweise vergleichen
Verfasst: 07.11.2010 21:21
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.