Pixel übereinstimmung

  • VB.NET

Es gibt 24 Antworten in diesem Thema. Der letzte Beitrag () ist von %P%.

    @kevin89: Das gefällt mir auch an deinem Code, dass sich der Vergleich nach dem kléineren Bild richtet ;)

    Ansonsten bin ich aber leider bisher auch nicht weiter also vorher. Ich weiß jetzt dass im vornherein eine gewisse Differenz vorhanden ist und warum das so ist, aber sollte sich der Bildvergleich nicht eher nach dem Orientieren was das menschliche Auge wahrnimmt?? Denn ich hab 2 Bilder die "SCHEINBAR" gleich aussehen, und daher will ich auch einen Vergleich durchführen, der auch nur die Differenzen registriert, die ich auch so sehen kann. Weil dann ist der Vergleich ja voll für'n Ar***, wenn ich vom sehen her eigentlich ein falsches ergebnis bekomme, auch wenn es rechnerisch/mathematisch vielleich ja korrekt sein mag



    Jemand ne Idee wie man das anstellen könnte, dass der Computer nicht "so streng" vergleicht?



    Danke %P% :thumbup:
    Hello World
    Da unser Auge nicht sooo perfekt ist wie eine Maschine (und auch viele Monitore nicht, was auch ein Faktor ist), dürfte eine Differenz von +=30 pro Farbwert uns noch nicht auffallen. Toleranz 25 sollte allgemein passen.

    VB.NET-Quellcode

    1. If Not (cl1.R > cl2.R - 25 And cl1.R < cl2.R + 25) Then difference += 1
    2. If Not (cl1.G > cl2.G - 25 And cl1.G < cl2.G + 25) Then difference += 1
    3. If Not (cl1.B > cl2.B - 25 And cl1.B < cl2.B + 25) Then difference += 1


    Im Zusammenhang also eine mögliche Lösung

    VB.NET-Quellcode

    1. Private Sub Process()
    2. Dim bmps() As Bitmap = Me.Invoke(New d_getbmps(AddressOf getbmps))
    3. Dim bmp1 As Bitmap = bmps(0)
    4. Dim bmp2 As Bitmap = bmps(1)
    5. Dim difference As Int64 = 0
    6. Dim pxs As Integer
    7. Dim faktor As Integer = 25
    8. For x As Integer = 0 To If(bmp1.Width > bmp2.Width, bmp2.Width, bmp1.Width) - 1
    9. For y As Integer = 0 To If(bmp1.Height > bmp2.Height, bmp2.Height, bmp1.Height) - 1
    10. Dim cl1 As Color = bmp1.GetPixel(x, y)
    11. Dim cl2 As Color = bmp2.GetPixel(x, y)
    12. If Not (cl1.R > cl2.R - faktor And cl1.R < cl2.R + faktor) Then difference += 1
    13. If Not (cl1.G > cl2.G - faktor And cl1.G < cl2.G + faktor) Then difference += 1
    14. If Not (cl1.B > cl2.B - faktor And cl1.B < cl2.B + faktor) Then difference += 1
    15. Next
    16. Me.Invoke(New d_dosome(AddressOf dosome), Math.Round(100 / (If(bmp1.Width > bmp2.Width, bmp2.Width, bmp1.Width) - 1) * x, 2) & " %")
    17. Next
    18. pxs = If(bmp1.Width > bmp2.Width, bmp2.Width, bmp1.Width) * If(bmp1.Height > bmp2.Height, bmp2.Height, bmp1.Height)
    19. Me.Invoke(New d_dosome(AddressOf dosome), Math.Round(difference / pxs, 2) & " (" & difference & " auf " & pxs & " px), das sind " & Math.Round((100 / pxs) * (difference / 3), 2) & " % Differenz.")
    20. End Sub


    btw dürfte Lockbits + Marshal schneller sein, falls die Performance nicht reicht.

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „kevin89“ ()

    sorry Beep!, dass die *.exe nicht gefunzt hat war nicht dein Fehler, und damit nun zu meinem nächsten Problem, ich kann keine exe-dateien mehr öffnen.


    %P%


    //EDIT2: Thx für dein Beispiel, ich werds nachher ausprobieren. Aber wieso machst nicht einfach pxs += 1, da versteh ich den Sinn noch ned. Und wofür Difference / pxs, was soll dabei rauskommen??? Denn auf die Variable Difference wird ja immer der Unterschied der R, G und B-Anteile dfaufgeschlagen. Was stellt Difference / pxs dar???? :thumbup:
    Hello World

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Link275“ ()

    Weil es unnötig ist, für jeden Pixel hochzuzählen und vor allem höchst unperformant. Lieber Breite * Höhe. Eigentlich hast du dir das hier gar nicht verdient, aber naja gut, aus langeweile geschrieben:

    VB.NET-Quellcode

    1. Public Class FastPixelCompare
    2. Public Structure FastPixelCompareResult
    3. Dim TotalValuesCompared As Int32
    4. Dim TotalDifference As Int32
    5. Dim DifferenceInPercent As Double
    6. End Structure
    7. Public Shared Function Compare(ByVal bmp1 As Bitmap, ByVal bmp2 As Bitmap, ByVal faktor As Integer) As FastPixelCompareResult
    8. Dim bmpdata1 As Imaging.BitmapData = bmp1.LockBits(New Rectangle(0, 0, bmp1.Width, bmp1.Height), Imaging.ImageLockMode.ReadOnly, Imaging.PixelFormat.Format24bppRgb)
    9. Dim bmpdata2 As Imaging.BitmapData = bmp2.LockBits(New Rectangle(0, 0, bmp2.Width, bmp2.Height), Imaging.ImageLockMode.ReadOnly, Imaging.PixelFormat.Format24bppRgb)
    10. Dim p1 As IntPtr = bmpdata1.Scan0
    11. Dim p2 As IntPtr = bmpdata2.Scan0
    12. Dim buffer1(bmp1.Height * bmpdata1.Stride) As Byte
    13. Dim buffer2(bmp2.Height * bmpdata2.Stride) As Byte
    14. System.Runtime.InteropServices.Marshal.Copy(p1, buffer1, 0, buffer1.Length)
    15. System.Runtime.InteropServices.Marshal.Copy(p2, buffer2, 0, buffer2.Length)
    16. bmp1.UnlockBits(bmpdata1)
    17. bmp2.UnlockBits(bmpdata2)
    18. Dim result As New FastPixelCompareResult With {.TotalValuesCompared = buffer1.Length + buffer2.Length}
    19. Dim diff As Int32 = 0
    20. For i As Integer = 0 To If(buffer1.Length > buffer2.Length, buffer2.Length - 1, buffer1.Length - 1)
    21. diff += If(buffer1(i) > buffer2(i) - faktor And buffer1(i) < buffer2(i) + faktor, 0, 1)
    22. Next
    23. result.TotalDifference = diff
    24. Dim pxs As Integer= If(bmp1.Width > bmp2.Width, bmp2.Width, bmp1.Width) * If(bmp1.Height > bmp2.Height, bmp2.Height, bmp1.Height)
    25. result.DifferenceInPercent = (100 / pxs) * (diff / 3)
    26. Return result
    27. End Function
    28. End Class

    Schneller geht ein Bildvergleich nicht, bis zu 50x schneller als die pixelweise Methode die du zZ. verwendest. Irgendwas in der Prozentberechnung stimmt noch nicht, aber das musst du selbst rausfinden. Aufrufbeispiel:

    VB.NET-Quellcode

    1. Dim diff As FastPixelCompare.FastPixelCompareResult = FastPixelCompare.Compare(PictureBox1.Image, PictureBox2.Image, 25)
    2. MsgBox("Total: " & diff.TotalValuesCompared & vbNewLine & "Difference: " & diff.TotalDifference & vbNewLine & "Diff in percent: " & diff.DifferenceInPercent)

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „kevin89“ ()

    also danke für den Code, der taugt echt richtig gut! :thumbup: Ich versuch grade den aufbau deines Codes zu verstehen ;) Aber was ja total geil is, is ja, wie schnell der die Vergleicht. Coole sache 8-)
    Momentan mach ich mich grade über Lockbits schlau, erste mal dass ich davon gehört hab, musst erstma nachsehen :rolleyes:.
    Ich hab nu im anschluss dazu gleich noch ne andere Frage, kommt jetz spontan ;). Und zwar folgendes: hab zwei Pics in meinen Picturboxen. Beide Bilder sind verschieden. haben aber einen gewissen Bereich in dem sie sich gleichen, jedoch haben beide bilder diese an verschiedenen Stellen.
    Wie stell ich denn nun eine Übereinstimmung fest, wenn der Teil, den beide Bilder gemeinsam haben, bei beiden an verschiedenen Stellen ist?

    Danke

    @kevin89: Top, thx :thumbup:
    Hello World