Grafik pixelweise vergleichen
Grafik pixelweise vergleichen
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
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
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:
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
Etwas optimiert, so dass es schneller beim Ermitteln ist:
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.
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
Re: Grafik pixelweise vergleichen
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
Da kann ich ein wenig rumprobieren.
Grüße,
Torsten
Re: Grafik pixelweise vergleichen

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
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"!
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?
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
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)
Re: Grafik pixelweise vergleichen
@Regenduft
Ich habs "schnell mal zusammengeschrieben".
Mit dem Buffer kann man allerdings auch machen, so spart man zwei Arrays.
Ich habs "schnell mal zusammengeschrieben".
Mit dem Buffer kann man allerdings auch machen, so spart man zwei Arrays.
Re: Grafik pixelweise vergleichen
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.Regenduft hat geschrieben: Frage: Ist das zuverlässig? Die Adressen müssten ja eigentlich statisch sein...
Zu mir kommen behinderte Delphine um mit mir zu schwimmen.
Wir fordern mehr Aufmerksamkeit für umfallende Reissäcke!
Wir fordern mehr Aufmerksamkeit für umfallende Reissäcke!

Re: Grafik pixelweise vergleichen
Bemängelst du folgendes?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?
Code: Alles auswählen
For y=0 To height-1
For x=0 To width-1
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
Re: Grafik pixelweise vergleichen
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...
Ich hatte den Pitch ignoriert, da ich dachte er wäre bei 32Bit Grafiken immer Breite*4.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 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...

PureBasic 5.73 LTE x86/x64 | Windows 7 (x64)