Free to the community: Motion Detection...A red Highlight will appear around your movements, working out bugs on system beep if anyone has insight?

Justin

Member
Joined
May 1, 2025
Messages
6
Programming Experience
10+
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:
Back
Top Bottom