Dunque, ricollegandomi alla discussione di acquisizione di immagini da Webcam, ho creato un'applicazione che, confrontanto i fotogrammi delle cam e impostando ovviamente delle soglie sia di luminosità che di numero di pixel in cui è avvenuto un cambiamento di luminosità, mi dice se c'è stato un cambiamento tra un fotogramma e l'altro e quindi del movimento.
Ora parte del codice che gestisce tutto questo é
La sequenza è abbastanza semplice e intuitiva:codice:Private Function ControlImage(ByVal immagine_or As Image, ByVal immagine_new As Image) As Boolean Try Dim esito As Boolean Dim bm_or As Bitmap Dim bm_new As Bitmap Dim bmpData_or As System.Drawing.Imaging.BitmapData Dim bmpData_new As System.Drawing.Imaging.BitmapData Dim rect_or As Rectangle Dim rect_new As Rectangle Dim ptr_or As IntPtr Dim ptr_new As IntPtr Dim bytes As Integer bm_or = New Bitmap(immagine_or) bm_new = New Bitmap(immagine_new) 'Estrazione dei colori nell'immagine del primo fotogramma rect_or = New Rectangle(0, 0, bm_or.Width, bm_or.Height) bmpData_or = bm_or.LockBits(rect_or, Drawing.Imaging.ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb) ' Get the address of the first line. ptr_or = bmpData_or.Scan0 bytes = bm_or.Width * bm_or.Height * 3 Dim rgbValues_or(bytes - 1) As Byte ' Copy the RGB values into the array. System.Runtime.InteropServices.Marshal.Copy(ptr_or, rgbValues_or, 0, bytes) 'Estrazione dei colori nell'immagine del secondo fotogramma rect_new = New Rectangle(0, 0, bm_new.Width, bm_new.Height) bmpData_new = bm_new.LockBits(rect_new, Drawing.Imaging.ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb) ptr_new = bmpData_new.Scan0 Dim rgbValues_new(bytes - 1) As Byte Dim pixelBytes As Integer = 3 ' Copy the RGB values into the array. System.Runtime.InteropServices.Marshal.Copy(ptr_new, rgbValues_new, 0, bytes) ' Unlock the bits. bm_new.UnlockBits(bmpData_new) '************************************************************* Dim diffPix As Integer Dim lumaPixel As Double Dim Max As Double Dim Min As Double Dim temp As Double Dim temp2 As Double Dim pos As Integer Dim scanPixel As Integer Dim listaPointX As New List(Of Integer) Dim listaPointY As New List(Of Integer) PixelChanged = 0 scanPixel = 0 '********************************************************* For Y As Integer = 0 To bm_or.Height - 1 Step scanPixSixeY For X As Integer = 0 To bm_or.Width - 1 Step scanPixSixeX pos = (Y * bmpData_new.Stride) + (X * pixelBytes) diffPix = CInt(rgbValues_new(pos)) - CInt(rgbValues_or(pos)) scanPixel += 1 'Calcolo luminosità lumaPixel = rgbValues_or(pos) / 255 Max = 0 Min = 1 If lumaPixel > Max Then Max = lumaPixel If lumaPixel < Min Then Min = lumaPixel temp = System.Math.Min(((Max + Min) / 2 * 255), 255) temp2 += temp '****************** If (rgbValues_new(pos) >= SensibiltàColoriView.B AndAlso System.Math.Abs(diffPix) > (rgbValues_or(pos) * SensibilitaColore)) Then PixelChanged += 1 listaPointX.Add(X) listaPointY.Add(Y) rgbValues_or(pos + 2) = PixelChangedColor.R 'Red rgbValues_or(pos + 1) = PixelChangedColor.G 'Green rgbValues_or(pos) = PixelChangedColor.B 'Blue If esito = False AndAlso PixelChanged > SensilitàPixel Then esito = True End If End If Next Next luminosity = temp2 / scanPixel listaPointX.Sort() listaPointY.Sort() '************************************************************* System.Runtime.InteropServices.Marshal.Copy(rgbValues_or, 0, ptr_or, bytes) bm_or.UnlockBits(bmpData_or) Dim myPoint(1) As Point If listaPointX.Count > 0 Then myPoint(0).X = listaPointX(0) If listaPointY.Count > 0 Then myPoint(0).Y = listaPointY(0) If listaPointX.Count > 0 Then myPoint(1).X = listaPointX(listaPointX.Count - 1) If listaPointY.Count > 0 Then myPoint(1).Y = listaPointY(listaPointY.Count - 1) RaiseEvent PixelChangedView(bm_or, bm_new, esito, PixelChanged, luminosity, myPoint) bm_or.Dispose() bm_or = Nothing bm_new.Dispose() bm_new = Nothing rect_or = Nothing rect_new = Nothing img1 = img2.Clone img2.Dispose() img2 = Nothing listaPointX = Nothing listaPointY = Nothing TimeElapsed = System.Environment.TickCount - count Return esito Catch ex As Exception 'MsgBox(ex.Message) End Try End Function
-prendo il primo e il secondo fotogramma
-li converto in due matrici distinte, dove ogni matrice è composta dai valori RBG del singoli pixel nel formato R,G,B quindi se rgbValue è la mia matrice avrò:
rgbValue(0) = valore Blu pixel 1
rgbValue(1) = valore verde pixel 1
rgbValue(2) = valore rosso pixel 1
rgbValue(3) = valore Blu pixel 2
rgbValue(4) = valore verde pixel 2
rgbValue(5) = valore rosso pixel 2
- Confronto le due matrici e traggo le mie conclusioni.
Ora le mie domando sono:
1-E' meglio confrontare le due matrici così come sono composte, ovvero:
oppure in questo modo:codice:For pos As Integer = 0 To rgbValue.Length - 1 Step 3 pixB = rgbValue(pos ) 'Valore pixel blu pixG = rgbValue(pos + 1) 'Valore pixel verde pixR = rgbValue(pos + 2) 'Valore pixel rosso Next
2-Cosa posso fare per velocizzare l'esecuzione? (per un fotogramma da 640x480 sul mio PC l'elaborazione avviene in circa 50 ms)codice:For Y As Integer = 0 To bm_or.Height - 1 For X As Integer = 0 To bm_or.Width - 1 pos = (Y * bmpData_new.Stride) + (X * pixelBytes) pixB = rgbValue(pos) pixG = rgbValue(pos +1) pixR = rgbValue(pos +2) Next Next
L'ouput a video dell'applizazione è:
![]()

Rispondi quotando