MotionDetection
' translated in VB:NET from c#
' by Giuseppe Di Santo - Studio IT
Imports System
Imports System.Collections.Generic
Imports System.ComponentModel
Imports System.Data
Imports System.Drawing
Imports System.Text
Imports System.Windows.Forms
Imports Emgu.CV
Imports Emgu.CV.Structure
Imports Emgu.Util
Imports System.Threading
Imports System.Runtime.InteropServices
Public Class MotionDetection
Private _capture As Capture
Private _motionHistory As MotionHistory
Private _forgroundDetector As VideoSurveillance.IBGFGDetector(Of Bgr)
Private Sub MotionDetection_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
'try to create the capture
If _capture Is Nothing Then
Try
_capture = New Capture()
Catch excpt As NullReferenceException
'show errors if there is any
MessageBox.Show(excpt.Message)
End Try
End If
If _capture IsNot Nothing Then
'if camera capture has been successfully created
'in second, the duration of motion history you wants to keep
'in second, parameter for cvCalcMotionGradient
_motionHistory = New MotionHistory(1.0, 0.05, 0.5)
'in second, parameter for cvCalcMotionGradient
AddHandler Application.Idle, AddressOf ProcessFrame
End If
End Sub
Private Sub ProcessFrame(ByVal sender As Object, ByVal e As EventArgs)
Using image As Image(Of Bgr, [Byte]) = _capture.QueryFrame()
Using storage As New MemStorage()
'create storage for motion components
If _forgroundDetector Is Nothing Then
'_forgroundDetector = new BGCodeBookModel<Bgr>();
'_forgroundDetector = new FGDetector<Bgr>(Emgu.CV.CvEnum.FORGROUND_DETECTOR_TYPE.FGD);
_forgroundDetector = New VideoSurveillance.BGStatModel(Of Bgr)(image, Emgu.CV.CvEnum.BG_STAT_TYPE.FGD_STAT_MODEL)
End If
_forgroundDetector.Update(image)
capturedImageBox.Image = image
'update the motion history
_motionHistory.Update(_forgroundDetector.ForgroundMask)
'#Region "get a copy of the motion mask and enhance its color"
Dim minValues As Double(), maxValues As Double()
Dim minLoc As Point(), maxLoc As Point()
_motionHistory.Mask.MinMax(minValues, maxValues, minLoc, maxLoc)
Dim motionMask As Image(Of Gray, [Byte]) = _motionHistory.Mask.Mul(255.0 / maxValues(0))
'#End Region
'create the motion image
Dim motionImage As Image(Of Bgr, [Byte]) = New Image(Of Bgr, Byte)(motionMask.Size)
'display the motion pixels in blue (first channel)
motionImage(0) = motionMask
'Threshold to define a motion area, reduce the value to detect smaller motion
Dim minArea As Double = 100
storage.Clear()
'clear the storage
Dim motionComponents As Seq(Of MCvConnectedComp) = _motionHistory.GetMotionComponents(storage)
'iterate through each of the motion component
For Each comp As MCvConnectedComp In motionComponents
'reject the components that have small area;
If comp.area < minArea Then
Continue For
End If
' find the angle and motion pixel count of the specific area
Dim angle As Double, motionPixelCount As Double
_motionHistory.MotionInfo(comp.rect, angle, motionPixelCount)
'reject the area that contains too few motion
If motionPixelCount < comp.area * 0.05 Then
Continue For
End If
'Draw each individual motion in red
DrawMotion(motionImage, comp.rect, angle, New Bgr(Color.Red))
Next
' find and draw the overall motion angle
Dim overallAngle As Double, overallMotionPixelCount As Double
_motionHistory.MotionInfo(motionMask.ROI, overallAngle, overallMotionPixelCount)
DrawMotion(motionImage, motionMask.ROI, overallAngle, New Bgr(Color.Green))
'Display the amount of motions found on the current image
UpdateText([String].Format("Total Motions found: {0}; Motion Pixel count: {1}", motionComponents.Total, overallMotionPixelCount))
'Display the image of the motion
motionImageBox.Image = motionImage
End Using
End Using
End Sub
Private Sub UpdateText(ByVal text As [String])
label3.Text = text
End Sub
Private Shared Sub DrawMotion(ByVal image As Image(Of Bgr, [Byte]), ByVal motionRegion As Rectangle, ByVal angle As Double, ByVal color As Bgr)
Dim circleRadius As Single = (motionRegion.Width + motionRegion.Height) >> 2
Dim center As New Point(motionRegion.X + motionRegion.Width >> 1, motionRegion.Y + motionRegion.Height >> 1)
Dim circle As New CircleF(center, circleRadius)
Dim xDirection As Integer = CInt(Math.Truncate(Math.Cos(angle * (Math.PI / 180.0)) * circleRadius))
Dim yDirection As Integer = CInt(Math.Truncate(Math.Sin(angle * (Math.PI / 180.0)) * circleRadius))
Dim pointOnCircle As New Point(center.X + xDirection, center.Y - yDirection)
Dim line As New LineSegment2D(center, pointOnCircle)
image.Draw(circle, color, 1)
image.Draw(line, color, 2)
End Sub
End Class
<< back to index
|