Motion Detection mit LockBits

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 1 Antwort in diesem Thema. Der letzte Beitrag () ist von RodFromGermany.

    Motion Detection mit LockBits

    Heyho zusammen

    Mein Versuch eine Bewegungserkennung zu programmieren scheitert gerade.
    Ziel ist es die geänderten Pixel rot zu markieren.

    Die Funktion erhält zwei Bitmaps mit der Auflösung 640x480. Transparenz nicht vorhanden (RGB).

    Die einzelnen Bytes werden ermittelt, als Farbe erkannt und danach verglichen.
    Ist ein Unterschied zu erkennen, müsste das Bild an diesem Pixel rot werden.
    Im anderen Fall sollte die originale Farbe übernommen werden.

    bmp_standard enthält das Standbild, bmp_camera das aktuelle Frame der Webcam. bmp_difference sollte das Bild enthalten, das den Unterschied aufzeigt.

    Mein Versuch sieht so aus:

    VB.NET-Quellcode

    1. ​Private Function generateDiffrence(ByVal bmp_standard As Bitmap, ByVal bmp_camera As Bitmap) As Bitmap
    2. ' Bei beiden Bitmaps alle Bild-Daten im Speicher sperren
    3. Dim bmp_difference As New Bitmap(bmp_standard.Width, bmp_standard.Height, PixelFormat.Format24bppRgb)
    4. Dim rect_imagesize As New Rectangle(0, 0, bmp_standard.Width, bmp_standard.Height)
    5. Dim bmpdata_standard As BitmapData = bmp_standard.LockBits(rect_imagesize, ImageLockMode.ReadOnly, bmp_difference.PixelFormat)
    6. Dim bmpdata_camera As BitmapData = bmp_camera.LockBits(rect_imagesize, ImageLockMode.ReadOnly, bmp_difference.PixelFormat)
    7. Dim bmpdata_difference As BitmapData = bmp_difference.LockBits(rect_imagesize, ImageLockMode.WriteOnly, bmp_difference.PixelFormat)
    8. Dim bytes As Integer = bmpdata_standard.Stride * bmpdata_standard.Height
    9. Dim bytes_standard(bytes - 1), bytes_camera(bytes - 1), bytes_diffrence(bytes - 1) As Byte
    10. ' Die gesperrten Bilddaten in 3 Bytearrays kopieren
    11. InteropServices.Marshal.Copy(bmpdata_standard.Scan0, bytes_standard, 0, bytes)
    12. InteropServices.Marshal.Copy(bmpdata_camera.Scan0, bytes_camera, 0, bytes)
    13. InteropServices.Marshal.Copy(bmpdata_difference.Scan0, bytes_diffrence, 0, bytes)
    14. ' Bitmaps vergleichen
    15. For idx As Integer = 0 To bytes - 1 Step 3 ' Offset 3?
    16. Dim clr_standard As Color = Color.FromArgb(bytes_standard(idx + 2), bytes_standard(idx + 1), bytes_standard(idx + 0))
    17. Dim clr_camera As Color = Color.FromArgb(bytes_camera(idx + 2), bytes_camera(idx + 1), bytes_camera(idx + 0))
    18. If Not clr_standard.Equals(clr_camera) Then
    19. bytes_diffrence(idx + 2) = 255 'R
    20. bytes_diffrence(idx + 1) = 0 'G
    21. bytes_diffrence(idx + 0) = 0 'B
    22. Else
    23. bytes_diffrence(idx + 2) = bytes_camera(idx + 2) 'R
    24. bytes_diffrence(idx + 1) = bytes_camera(idx + 1) 'G
    25. bytes_diffrence(idx + 0) = bytes_camera(idx + 0) 'B
    26. End If
    27. Next
    28. ' Daten und Ressourcen freigeben
    29. bmp_standard.UnlockBits(bmpdata_standard)
    30. bmp_camera.UnlockBits(bmpdata_camera)
    31. bmp_difference.UnlockBits(bmpdata_difference)
    32. 'Rückgabe
    33. Return bmp_difference
    34. End Function


    Jedoch bleibt das Bild komplett schwarz, obwohl zwei gefüllte Bitmaps übergeben werden.

    Wo liegt der Fehler?

    Gruss & Danke
    Dancger
    MESS WITH THE BEST, DIE LIKE THE REST! :evil:
    n'paar Links: DNS Tools, Steal WA DB, Droidsheep...

    Dancger schrieb:

    Wo liegt der Fehler?
    bytes_diffrence werden zwar befüllt, nicht aber in das Diff-Bild zurückkopiert.
    In C# ginge das mit unsafe und ohne copy.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!