Rythorian
RYTHORIAN
- Joined
- Nov 5, 2024
- Messages
- 54
- Programming Experience
- 5-10
Motion Detection:
This application is designed for motion detection using video input devices. The application captures video frames, processes them to detect motion. The detected motion will be highlighted in red. It is a practical implementation of video processing and motion detection techniques, leveraging the AForge.NET framework. I do have a few bugs to work out, when motion is detected, a system beep is supposed to occur, if I can figure this out I would be grateful.Main Concepts To Understand:
The application utilizes several key concepts:Video Capture: It captures video from available input devices (cameras).
Motion Detection: It processes video frames to identify motion using a motion detector.
User Interface: It provides a graphical user interface (GUI) for user interaction, allowing users to select cameras and start/stop motion detection.
Timers: It employs timers to manage periodic actions, such as sound alerts when motion is detected.
Structuring Of Code:
Several components to consider:Imports: Necessary libraries from AForge.NET for video processing and motion detection.
Class Definition: The main class Form1 contains all the logic for the application.
Variables: It declares variables for video devices, motion detection, and UI elements.
Event Handlers: It includes event handlers for form loading, button clicks, and frame processing.
This app effectively demonstrates the integration of video processing and user interaction. By utilizing the AForge.NET framework, it captures video, detects motion, and provides real-time feedback to the user.
Motion Detection:
REM: Created by: Justin Linwood Ross | Creation Date: 4/29/25 11:30 AM | Last Modified: 4/30/25 5:30 PM | Github: rythorian77
Imports System.Media ' For playing system sounds
Imports AForge.Video ' For video processing
Imports AForge.Video.DirectShow ' For accessing video capture devices
Imports AForge.Vision.Motion ' For MessageBox, Timer, PictureBox, Label, ComboBox, Button, FormClosingEventArgs
Public Class Form1
#Region "Variable Declarations"
' Declare variables for video devices and video source
Private videoDevices As FilterInfoCollection ' Collection of video input devices
Private videoSource As VideoCaptureDevice ' The video capture device selected by the user
Private Const MinimumMotionScore As Double = 0.005 ' This score is compared against motionDetector.MotionLevel to determine if motion is detected
' Declare a timer for periodic beeping when motion is detected
Private WithEvents BeepTimer As New Timer() ' Timer object to trigger periodic beeping
' Changed beep interval to 3000 ms (3 seconds)
Private Const BeepIntervalMs As Integer = 3000 ' Interval in milliseconds between each beep
' Added constant for the difference threshold in motion detection
' Adjust this value (0-255) - lower is more sensitive
Private Const DifferenceThreshold As Integer = 10 ' Threshold for detecting differences between frames
Private motionDetector As MotionDetector ' Motion detector object to process video frames
#End Region
#Region "Form Event Handlers"
' Event handler for form load
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
' Set the interval for the beep timer
BeepTimer.Interval = BeepIntervalMs
' Add event handler for the beep timer tick event
AddHandler BeepTimer.Tick, AddressOf BeepTimer_Tick
Try
' Get the collection of video input devices
videoDevices = New FilterInfoCollection(FilterCategory.VideoInputDevice)
' Check if any video devices are found
If videoDevices.Count = 0 Then
' Show an error message if no video devices are found
MessageBox.Show("No video input devices found.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
' Disable the start button since no devices are available
btnStart.Enabled = False
' Update the status label to indicate no devices are found
UpdateStatusLabel("No video input devices found.", Color.Red)
Else
' If video devices are found, add their names to the combo box
For Each device As FilterInfo In videoDevices
cboCameras.Items.Add(device.Name)
Next
' Set the default selected camera to the first one in the list
cboCameras.SelectedIndex = 0
' Enable the start button
btnStart.Enabled = True
' Disable the stop button (since the camera is not started yet)
btnStop.Enabled = False
' Enable the camera combo box for camera selection
cboCameras.Enabled = True
' Update the status label to prompt the user to select a camera and start it
UpdateStatusLabel("Select camera and press Start.", SystemColors.ControlText)
End If
Catch ex As Exception
' Handle any exceptions that occur during video device enumeration
MessageBox.Show("Error enumerating video devices: " & ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
' Disable the start and stop buttons, and the camera combo box
btnStart.Enabled = False
btnStop.Enabled = False
cboCameras.Enabled = False
' Update the status label to indicate an error during initialization
UpdateStatusLabel("Error initializing.", Color.Red)
End Try
End Sub
' Event handler for form closing
Private Sub MainForm_FormClosing(sender As Object, e As FormClosingEventArgs) Handles MyBase.FormClosing
' Ensure the camera is stopped when the form is closing
StopCamera()
End Sub
' Event handler for form shown event
Private Sub Form1_Shown(sender As Object, e As EventArgs) Handles MyBase.Shown
' Set the size mode of the picture box to zoom when the form is shown
pbCameraFeed.SizeMode = PictureBoxSizeMode.Zoom
End Sub
' Event handler for the picture box resize event
Private Sub PbCameraFeed_Resize(sender As Object, e As EventArgs) Handles pbCameraFeed.Resize
' Set the size mode of the picture box to zoom to fit the new size
pbCameraFeed.SizeMode = PictureBoxSizeMode.Zoom
End Sub
#End Region
#Region "Button Click Handlers"
' Event handler for the start button click
Private Sub BtnStart_Click(sender As Object, e As EventArgs) Handles btnStart.Click
' Check if a camera has been selected
If cboCameras.SelectedItem Is Nothing Then
' Show a warning message if no camera is selected
MessageBox.Show("Please select a camera.", "Selection Error", MessageBoxButtons.OK, MessageBoxIcon.Warning)
' Update the status label to indicate no camera is selected
UpdateStatusLabel("Please select a camera.", Color.OrangeRed)
' Return without starting the camera
Return
End If
Try
' Initialize the video source with the selected camera's moniker string
videoSource = New VideoCaptureDevice(videoDevices(cboCameras.SelectedIndex).MonikerString)
' Add event handler for the new frame event
AddHandler videoSource.NewFrame, AddressOf VideoSource_NewFrame
' Start the video source (camera)
videoSource.Start()
' Initialize the motion detector with the specified DifferenceThreshold
' TwoFramesDifferenceDetector is used to compare the current frame with the previous one
' MotionBorderHighlighting is used to highlight the motion detected area in the frame
motionDetector = New MotionDetector(New TwoFramesDifferenceDetector(DifferenceThreshold), New MotionBorderHighlighting())
' Disable the start button after starting the camera
btnStart.Enabled = False
' Enable the stop button to allow stopping the camera
btnStop.Enabled = True
' Disable the camera combo box while the camera is running
cboCameras.Enabled = False
' Update the status label to indicate that motion detection has started
UpdateStatusLabel("Processing Motion...", SystemColors.ControlText)
' Stop the beep timer if it was running
BeepTimer.Stop()
Catch ex As Exception
' Handle any exceptions that occur during initialization
MessageBox.Show("Error starting camera: " & ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
' Disable the start button
btnStart.Enabled = False
' Disable the stop button
btnStop.Enabled = False
' Enable the camera combo box for user to make a selection
cboCameras.Enabled = True
' Update the status label to indicate an error during initialization
UpdateStatusLabel("Error initializing camera.", Color.Red)
End Try
End Sub
' Event handler for the stop button click
Private Sub BtnStop_Click(sender As Object, e As EventArgs) Handles btnStop.Click
' Call the StopCamera subroutine to stop the video source and reset UI elements
StopCamera()
End Sub
#End Region
#Region "Video Source Event Handlers"
' Event handler for new frames captured by the video source
Private Sub VideoSource_NewFrame(sender As Object, eventArgs As NewFrameEventArgs)
' Clone the current frame to avoid issues with the frame being used by the video source
Dim currentFrame As Bitmap = eventArgs.Frame.Clone()
' Variable to store the motion score of the current frame
' The motion score is a property of the motion detector after processing
Dim motionScore As Double = 0.0
Try
' Check if motion detector is initialized
If motionDetector IsNot Nothing Then
' Process the current frame to detect motion and get the motion level
' The ProcessFrame method returns a boolean indicating if motion was detected,
' and the motion level is stored in the MotionLevel property.
motionDetector.ProcessFrame(currentFrame)
' Check if the motion score meets or exceeds the minimum motion score threshold
If motionScore >= MinimumMotionScore Then
' Motion detected: Update status and manage beeping
UpdateStatusLabel($"MOTION DETECTED! ({motionScore:P4})", Color.Red)
' If the beep timer is not enabled, start it.
' The beep will now be played by the timer's Tick event.
If Not BeepTimer.Enabled Then
BeepTimer.Start()
End If
Else
' No significant motion detected: Update status to "Processing Motion..."
UpdateStatusLabel("Processing Motion...", SystemColors.ControlText)
' Stop the beep timer if motion stops
BeepTimer.Stop()
End If
Else
' Handle the case where the motion detector is not initialized
UpdateStatusLabel("Motion detector not initialized.", SystemColors.ControlText)
' Stop the beep timer if the detector isn't ready
BeepTimer.Stop()
End If
' Update the picture box to display the current frame
' Ensure the UI update is performed on the main thread using Invoke
Me.Invoke(Sub()
' Dispose the previous image in the picture box if it exists
pbCameraFeed.Image?.Dispose()
' Set the picture box's image to the current frame
pbCameraFeed.Image = currentFrame
End Sub)
Catch ex As Exception
' Handle any exceptions that occur during frame processing
Me.Invoke(Sub()
' Write the error message to the debug output
Debug.WriteLine("Error in camera feed processing: " & ex.Message)
' Show an error message box to the user
MessageBox.Show("Error in camera feed processing: " & ex.Message, "Processing Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
' Stop the camera and reset UI elements in case of an error
StopCamera()
End Sub)
' Dispose the current frame if an exception occurred
If currentFrame IsNot Nothing Then currentFrame.Dispose()
End Try
End Sub
#End Region
#Region "Timer Event Handlers"
' Event handler for the beep timer tick event
Private Sub BeepTimer_Tick(sender As Object, e As EventArgs) Handles BeepTimer.Tick
' Play the system beep sound
SystemSounds.Beep.Play()
' The timer remains enabled and will tick again after BeepIntervalMs if motion persists
End Sub
#End Region
#Region "Helper Subroutines"
' Subroutine to stop the camera and reset UI elements
Private Sub StopCamera()
' Check if video source is not null and is currently running
If videoSource IsNot Nothing AndAlso videoSource.IsRunning Then
Try
' Remove the event handler for the new frame event
RemoveHandler videoSource.NewFrame, AddressOf VideoSource_NewFrame
' Signal the video source to stop capturing frames
videoSource.SignalToStop()
' Wait for the video source to stop
videoSource.WaitForStop()
' Set the video source to null after stopping
videoSource = Nothing
' Dispose the image in the picture box if it exists and set it to null
If pbCameraFeed.Image IsNot Nothing Then
pbCameraFeed.Image.Dispose()
pbCameraFeed.Image = Nothing
End If
' Set motion detector to null after stopping the camera
motionDetector = Nothing
' Stop the beep timer
BeepTimer.Stop()
' Enable the start button
btnStart.Enabled = True
' Disable the stop button
btnStop.Enabled = False
' Enable the camera combo box
cboCameras.Enabled = True
' Update the status label to indicate that the camera has been stopped
UpdateStatusLabel("Camera stopped.", SystemColors.ControlText)
Catch ex As Exception
' Handle any exceptions that occur during stopping the camera
MessageBox.Show("Error stopping camera: " & ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
' Enable the start button in case of an error
btnStart.Enabled = True
' Disable the stop button
btnStop.Enabled = False
' Enable the camera combo box for user to make a selection
cboCameras.Enabled = True
' Update the status label to indicate an error during stopping
UpdateStatusLabel("Error stopping camera.", Color.Red)
End Try
End If
End Sub
' Subroutine to update the status label text and color
Private Sub UpdateStatusLabel(text As String, color As Color)
' Ensure the UI update is performed on the main thread using Invoke
Me.Invoke(Sub()
' Set the text of the status label
lblStatus.Text = text
' Set the color of the status label text
lblStatus.ForeColor = color
End Sub)
End Sub
#End Region
End Class
Last edited: