Logo
Acquisti Giochi Scienza Affari Notizie Societè Casa
Regionale Sport Computer Salute Tempo libero Consultazione  


Calcultate Optical Flow PyrLK

' inspired by Opencv lkdemo.c sample

' by Giuseppe Di Santo - Studio IT

 

Public Class cvCalcOpticalFlowPyrLK

 

    Private captureCV As Emgu.CV.Capture

    Private captureInProgress As Boolean

    Const radius = 5

    Dim defineCorners As Boolean = False

 

    Dim puntiA(0)() As PointF

    Dim puntiB(0)() As PointF

    Dim puntiTemp As PointF()()

 

    Dim puntiBtemp(0)() As PointF

    Dim add_remove_pt As Boolean = False

 

 

    Dim count As Integer = 0

    Dim frame As Emgu.CV.Image(Of Emgu.CV.Structure.Bgr, Byte)

 

    Dim grayA As Emgu.CV.Image(Of Emgu.CV.Structure.Gray, Byte)

    Dim grayB As Emgu.CV.Image(Of Emgu.CV.Structure.Gray, Byte)

 

    Dim pyrBufferA As Emgu.CV.Image(Of Emgu.CV.Structure.Gray, Byte)

    Dim pyrBufferB As Emgu.CV.Image(Of Emgu.CV.Structure.Gray, Byte)

 

    Dim imgTemp As Emgu.CV.Image(Of Emgu.CV.Structure.Gray, Byte)

    Dim flags As Emgu.CV.CvEnum.LKFLOW_TYPE = Emgu.CV.CvEnum.LKFLOW_TYPE.DEFAULT

 

    Dim status As Byte()

    Dim errors As Single()

 

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        If (captureCV Is Nothing) Then

            Try

                captureCV = New Emgu.CV.Capture

            Catch excpt As NullReferenceException

                MessageBox.Show(excpt.Message)

            End Try

        End If

        If (Not captureCV Is Nothing) Then

            If captureInProgress Then

                Me.Button1.Text = "Start Capture"

                RemoveHandler Application.Idle, New EventHandler(AddressOf Me.ProcessFrame)

            Else

                Me.Button1.Text = "Stop"

                AddHandler Application.Idle, New EventHandler(AddressOf Me.ProcessFrame)

 

                ' set form and Imagebox size

                Dim frame As Emgu.CV.Image(Of Emgu.CV.Structure.Bgr, Byte) = captureCV.QueryFrame

                grayA = frame.Convert(Of Emgu.CV.Structure.Gray, Byte)()

 

                pyrBufferA = New Emgu.CV.Image(Of Emgu.CV.Structure.Gray, Byte)(frame.Width + 8, frame.Height / 3)

                pyrBufferB = New Emgu.CV.Image(Of Emgu.CV.Structure.Gray, Byte)(frame.Width + 8, frame.Height / 3)

 

                ' dimensiona i riquadri

                ImageBox1.Width = frame.Width

                ImageBox1.Height = frame.Height

                Me.Width = frame.Width + 30

                Me.Height = frame.Height + 100

 

            End If

            captureInProgress = Not captureInProgress

        End If

    End Sub

 

    ' add points with GoodFeaturesToTrack

    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click

        defineCorners = True

    End Sub

 

 

    ' add one point where the user clicks

    Private Sub ImageBox1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles ImageBox1.MouseDown

        If e.Button = MouseButtons.Left Then

            Dim removedpoint As Boolean = False

            Dim radiussquare As Double = radius ^ 2

            'Dim puntitemp(0)() As PointF

 

            If count > 0 Then

                Dim k As Integer = 0

                For i As Integer = 0 To count - 1

                    Dim dx As Double = e.X - puntiB(0)(i).X

                    Dim dy As Double = e.Y - puntiB(0)(i).Y

                    If (dx * dx + dy * dy >= radiussquare) Then

                        puntiA(0)(k) = puntiA(0)(i)

                        k += 1

                    Else

                        removedpoint = True

                    End If

                Next

                count = k

            End If

 

            If Not removedpoint Then

                puntiBtemp(0) = New PointF() {New PointF(e.X, e.Y)}

                add_remove_pt = True

            End If

        End If

    End Sub

 

    Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click

        count = 0

    End Sub

 

 

    'Dim times(1000) As Double

    'Dim ii As Integer

    Private Sub ProcessFrame(ByVal sender As Object, ByVal arg As EventArgs)

        frame = captureCV.QueryFrame

 

        grayB = frame.Convert(Of Emgu.CV.Structure.Gray, Byte)()

 

        If defineCorners Then

            count = 500

            puntiB = grayB.GoodFeaturesToTrack(count, 0.01, 10, 3)

            grayB.FindCornerSubPix(puntiB, New System.Drawing.Size(10, 10), New System.Drawing.Size(-1, -1), New Emgu.CV.Structure.MCvTermCriteria(20, 0.03))

 

            count = puntiB(0).Length

            defineCorners = False

        ElseIf count > 0 Then

 

            'Dim start_time As Date = Now

 

            ' my overridden function with the "count" parameter added

            Emgu.CV.OpticalFlow.PyrLK(grayA, grayB, pyrBufferA, pyrBufferB, count, puntiA(0), New Size(10, 10), 3, New Emgu.CV.Structure.MCvTermCriteria(20, 0.03D), flags, puntiB(0), status, errors)

            flags = Emgu.CV.CvEnum.LKFLOW_TYPE.CV_LKFLOW_PYR_A_READY

 

            '' counts seconds from start_time declaration

            'Dim stop_time As Date = Now

            'Dim elapsed_time As TimeSpan = stop_time.Subtract(start_time)

            'Dim timestamp As Double = elapsed_time.TotalMilliseconds / 1000

            'times(ii) = timestamp

            'ii += 1

 

 

 

            'Dim col1 As New Emgu.CV.Structure.Bgr(0, 255, 255)

            'For Each pt As PointF In puntiA(0)

            '    Dim cr As New Emgu.CV.Structure.CircleF(pt, 1)

            '    frame.Draw(cr, col1, 1)

            'Next

 

            Dim k As Integer = 0

            Dim col2 As New Emgu.CV.Structure.Bgr(255, 255, 0)

            For i As Integer = 0 To count - 1

                If status(i) > 0 Then

                    Dim cr As New Emgu.CV.Structure.CircleF(puntiB(0)(i), 2)

 

                    puntiB(0)(k) = puntiB(0)(i)

 

                    frame.Draw(cr, col2, 2)

                    k += 1

                End If

            Next

            count = k

 

        End If

 

        If add_remove_pt Then

 

            grayB.FindCornerSubPix(puntiBtemp, New System.Drawing.Size(10, 10), New System.Drawing.Size(-1, -1), New Emgu.CV.Structure.MCvTermCriteria(20, 0.03))

 

            If count > 0 Then

                ReDim Preserve puntiB(0)(puntiB(0).Length)

                puntiB(0)(puntiB(0).Length - 1) = puntiBtemp(0)(0)

            Else

                puntiB(0) = puntiBtemp(0)

            End If

 

            count = puntiB(0).Length

            add_remove_pt = False

        End If

 

 

        ' swap images:

        imgTemp = grayA

        grayA = grayB

        grayB = imgTemp

        'swap pyramid

        imgTemp = pyrBufferA

        pyrBufferA = pyrBufferB

        pyrBufferB = imgTemp

        ' swap points:

        puntiTemp = puntiA

        puntiA = puntiB

        puntiB = puntiTemp

 

 

        ImageBox1.Image = frame

    End Sub

 

 

End Class

 

<< back to index