I need help on the system beep when motion is detected...A puzzle if you can solve it...
Ultimately I want the system beep to go off every 3 seconds when the red highlight surrounds your movement in the picturebox???. I can stay still and blink my eyes and this motion detection will target your eyes....Try it. I'll have great respect for anyone who can solve this here...
Motion Detection::
// REM: Created by: Justin Linwood Ross | Creation Date: 4/29/25 11:30 AM | Last Modified: 4/29/25 11:30 AM | Github: rythorian77
using System;
using System.Drawing;
using System.Windows.Forms;
using System.Media; // For playing system sounds
using AForge.Video; // For video processing
using AForge.Video.DirectShow; // For accessing video capture devices
using AForge.Vision.Motion; // For MotionDetector
// Ensure you have added references to:
// AForge.dll
// AForge.Video.dll
// AForge.Video.DirectShow.dll
// AForge.Vision.dll
namespace MotionDetectorApp // Replace with your application's namespace
{
// This class assumes you have a Windows Form named Form1 with the following controls:
// PictureBox named pbCameraFeed
// Label named lblStatus
// ComboBox named cboCameras
// Button named btnStart
// Button named btnStop
public partial class Form1 : Form
{
#region Variable Declarations
// Declare variables for video devices and video source
private FilterInfoCollection videoDevices; // Collection of video input devices
private VideoCaptureDevice videoSource; // The video capture device selected by the user
private const double MinimumMotionScore = 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 Timer BeepTimer = new Timer(); // Timer object to trigger periodic beeping
// Changed beep interval to 3000 ms (3 seconds)
private const int BeepIntervalMs = 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 int DifferenceThreshold = 10; // Threshold for detecting differences between frames
private MotionDetector motionDetector; // Motion detector object to process video frames
#endregion
// Constructor for the form
public Form1()
{
InitializeComponent(); // This call is required for the Windows Form Designer.
// Set the interval for the beep timer
BeepTimer.Interval = BeepIntervalMs;
// Add event handler for the beep timer tick event
BeepTimer.Tick += BeepTimer_Tick;
// Wire up Form event handlers (Handles clause in VB.NET is done here in C#)
this.Load += Form1_Load;
this.FormClosing += MainForm_FormClosing;
this.Shown += Form1_Shown;
// Wire up PictureBox event handler
pbCameraFeed.Resize += PbCameraFeed_Resize;
// Wire up Button event handlers
btnStart.Click += BtnStart_Click;
btnStop.Click += BtnStop_Click;
}
#region Form Event Handlers
// Event handler for form load
private void Form1_Load(object sender, EventArgs e)
{
try
{
// Get the collection of video input devices
videoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);
// Check if any video devices are found
if (videoDevices.Count == 0)
{
// 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
foreach (FilterInfo device in videoDevices)
{
cboCameras.Items.Add(device.Name);
}
// 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);
}
}
catch (Exception ex)
{
// 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);
}
}
// Event handler for form closing
private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
{
// Ensure the camera is stopped when the form is closing
StopCamera();
}
// Event handler for form shown event
private void Form1_Shown(object sender, EventArgs e)
{
// Set the size mode of the picture box to zoom when the form is shown
pbCameraFeed.SizeMode = PictureBoxSizeMode.Zoom;
}
// Event handler for the picture box resize event
private void PbCameraFeed_Resize(object sender, EventArgs e)
{
// Set the size mode of the picture box to zoom to fit the new size
pbCameraFeed.SizeMode = PictureBoxSizeMode.Zoom;
}
#endregion
#region Button Click Handlers
// Event handler for the start button click
private void BtnStart_Click(object sender, EventArgs e)
{
// Check if a camera has been selected
if (cboCameras.SelectedItem == null)
{
// 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;
}
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
videoSource.NewFrame += 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 (Exception ex)
{
// 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);
}
}
// Event handler for the stop button click
private void BtnStop_Click(object sender, EventArgs e)
{
// Call the StopCamera subroutine to stop the video source and reset UI elements
StopCamera();
}
#endregion
#region Video Source Event Handlers
// Event handler for new frames captured by the video source
private void VideoSource_NewFrame(object sender, NewFrameEventArgs eventArgs)
{
// Clone the current frame to avoid issues with the frame being used by the video source
Bitmap currentFrame = (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
double motionScore = 0.0; // Initialize motionScore
try
{
// Check if motion detector is initialized
if (motionDetector != null)
{
// 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);
// Get the motion level after processing the frame
motionScore = motionDetector.MotionLevel;
// Check if the motion score meets or exceeds the minimum motion score threshold
if (motionScore >= MinimumMotionScore)
{
// 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 (!BeepTimer.Enabled)
{
BeepTimer.Start();
}
}
else
{
// No significant motion detected: Update status to "Processing Motion..."
UpdateStatusLabel("Processing Motion...", SystemColors.ControlText);
// Stop the beep timer if motion stops
BeepTimer.Stop();
}
}
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();
}
// Update the picture box to display the current frame
// Ensure the UI update is performed on the main thread using Invoke
// Use Action for a more modern approach
this.Invoke((Action)(() =>
{
// Dispose the previous image in the picture box if it exists
if (pbCameraFeed.Image != null)
{
pbCameraFeed.Image.Dispose();
}
// Set the picture box's image to the current frame
pbCameraFeed.Image = currentFrame;
}));
}
catch (Exception ex)
{
// Handle any exceptions that occur during frame processing
this.Invoke((Action)(() =>
{
// Write the error message to the debug output
System.Diagnostics.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();
}));
// Dispose the current frame if an exception occurred
if (currentFrame != null) currentFrame.Dispose();
}
}
#endregion
#region Timer Event Handlers
// Event handler for the beep timer tick event
private void BeepTimer_Tick(object sender, EventArgs e)
{
// Play the system beep sound
SystemSounds.Beep.Play();
// The timer remains enabled and will tick again after BeepIntervalMs if motion persists
}
#endregion
#region Helper Subroutines
// Subroutine to stop the camera and reset UI elements
private void StopCamera()
{
// Check if video source is not null and is currently running
if (videoSource != null && videoSource.IsRunning)
{
try
{
// Remove the event handler for the new frame event
videoSource.NewFrame -= 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 = null;
// Dispose the image in the picture box if it exists and set it to null
if (pbCameraFeed.Image != null)
{
pbCameraFeed.Image.Dispose();
pbCameraFeed.Image = null;
}
// Set motion detector to null after stopping the camera
motionDetector = null;
// 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 (Exception ex)
{
// 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);
}
}
}
// Subroutine to update the status label text and color
private void UpdateStatusLabel(string text, Color color)
{
// Ensure the UI update is performed on the main thread using Invoke
this.Invoke((Action)(() =>
{
// Set the text of the status label
lblStatus.Text = text;
// Set the color of the status label text
lblStatus.ForeColor = color;
}));
}
#endregion
// This method is required by the Windows Form Designer.
private void InitializeComponent()
{
// Auto-generated code for designer components will go here.
// You would typically create your form layout using the Visual Studio designer,
// which generates this method.
// For this code to compile and run, you need to have a Form1 with the specified controls.
// Example of how controls might be declared if not using the designer:
// this.pbCameraFeed = new System.Windows.Forms.PictureBox();
// this.lblStatus = new System.Windows.Forms.Label();
// this.cboCameras = new System.Windows.Forms.ComboBox();
// this.btnStart = new System.Windows.Forms.Button();
// this.btnStop = new System.Windows.Forms.Button();
// this.SuspendLayout();
// ... designer code ...
// this.ResumeLayout(false);
// this.PerformLayout();
}
// Declare the UI controls as members of the Form class
// These would typically be generated by the designer, but are listed here for clarity.
private System.Windows.Forms.PictureBox pbCameraFeed;
private System.Windows.Forms.Label lblStatus;
private System.Windows.Forms.ComboBox cboCameras;
private System.Windows.Forms.Button btnStart;
private System.Windows.Forms.Button btnStop;
}
}
Last edited: