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
|