How to implement motion detector in C#

On the following webpage you will find more information about implemention of motion detection function with your C# camera application using the Ozeki Camera SDK. With the help of this article you will be able to successfully set a threshold and detect motion events in the captured video stream. In order to succeed, Ozeki Camera SDK has to be installed and a reference to OzekiSDK.dll has to be added to your Visual Studio project.

Important: you should study this article in order to find out how to setup your Windows Forms Application correctly.

Getting started

To get started it is recomended to Download and Install the latest version of Ozeki Camera SDK. After installation you can find the example code discussed in this page with full source code in the following location on your harddisk:

Download Ozeki Camera SDK: https://www.camera-sdk.com/https://camera-sdk.com/p_6513-download-onvif-ozeki-camera-sdk-for-c-sharp.html
Windows forms version: C:\Users\user\Documents\Ozeki\Ozeki SDK\Examples\Camera\04_ComputerVision\14_MotionDetection

To compile this example you will need Microsoft Visual Studio installed on your computer.

Corporate use of motion detector

Motion detection marks a change in the position of an object relative to its surroundings. It is enough sensitive to recognize the slightest motion changed in the picture. This function became extremely popular in the field of security systems. People usually use it for monitoring their home, their stores or public areas where it is needed to obtain security. Another example for the effective use of motion detection is that you can benefit from it if you want to track the security of your home.

If you are a businessman with more hectares of manufactoring factories or you are the manager of a prison you may pay attention to stealing, or escaping from the jail during the night. With motion detection you can easily recognize these kinds of crimes as well. In the case of night records it is possible that the quality of the recording will not be satisfactory.

If you use the motion detection function of the Ozeki Camera SDK you will be able to detect motion events in the captured video stream even at night, which increases efficiently the security of your home or your business.

Implement motion detection in C#

C# code example for motion detection

Windows Form  

Windows forms version

MainForm.cs

using System;
using System.Windows.Forms;
using Ozeki.Camera;
using Ozeki.Media;
using Ozeki.Vision;

namespace MotionDetection_WF
{
    public partial class MainForm : Form
    {
        private OzekiCamera _camera;
        private MediaConnector _connector;
        private CameraURLBuilderWF _myCameraUrlBuilder;
        private ImageProcesserHandler _imageProcesserHandler;
        private ILicensePlateRecognizer _licensePlateRecognizer;
        private IMotionDetector _detector;
        private DrawingImageProvider _originalImageProvider;
        private DrawingImageProvider _processedImageProvider;

        public MainForm()
        {
            InitializeComponent();
        }

        void MainForm_Load(object sender, EventArgs e)
        {
            Init();

            SetVideoViewers();

            InitDetectorFields();

        }

        void Init()
        {
            _myCameraUrlBuilder = new CameraURLBuilderWF();
            _connector = new MediaConnector();
            _originalImageProvider = new DrawingImageProvider();
            _processedImageProvider = new DrawingImageProvider();

            _detector = ImageProcesserFactory.CreateMotionDetector();

            _imageProcesserHandler = new ImageProcesserHandler();
            _imageProcesserHandler.AddProcesser(_detector);

        }

        void SetVideoViewers()
        {
            OriginalViewer.SetImageProvider(_originalImageProvider);
            ProcessedViewer.SetImageProvider(_processedImageProvider);
        }

        void InitDetectorFields()
        {
            InvokeGuiThread(() =>
            {
                tb_Threshold.Text = _detector.Threshold.ToString();

                if (_detector.Mode == ThresholdMode.AVERAGE)
                    rbAverage.PerformClick();
                else if (_detector.Mode == ThresholdMode.SUM)
                    rbSum.PerformClick();
            });
        }

        void ConnectCam()
        {
            _connector.Connect(_camera.VideoChannel, _originalImageProvider);

            _connector.Connect(_camera.VideoChannel, _imageProcesserHandler);
            _connector.Connect(_imageProcesserHandler, _processedImageProvider);

        }

        void Start()
        {
            OriginalViewer.Start();
            ProcessedViewer.Start();

            _camera.Start();
            _imageProcesserHandler.Start();
        }

        void btn_Set_Click(object sender, EventArgs e)
        {
            InvokeGuiThread(() =>
            {
                _detector.Threshold = Int32.Parse(tb_Threshold.Text);
                if (rbAverage.Checked)
                    _detector.Mode = ThresholdMode.AVERAGE;
                else if (rbSum.Checked)
                    _detector.Mode = ThresholdMode.SUM;
            });
        }

        void InvokeGuiThread(Action action)
        {
            BeginInvoke(action);
        }

        private void button_Compose_Click(object sender, EventArgs e)
        {
            var result = _myCameraUrlBuilder.ShowDialog();

            if (result != DialogResult.OK) return;

            tb_cameraUrl.Text = _myCameraUrlBuilder.CameraURL;

            button_Connect.Enabled = true;
        }

        private void button_Connect_Click(object sender, EventArgs e)
        {
            if (_camera != null)
            {
                _camera.CameraStateChanged -= _camera_CameraStateChanged;
                _camera.Disconnect();
                _connector.Disconnect(_camera.VideoChannel, _processedImageProvider);
                _connector.Disconnect(_camera.VideoChannel, _originalImageProvider);
                _camera.Dispose();
                _camera = null;
            }

            _camera = new OzekiCamera(_myCameraUrlBuilder.CameraURL);
            _camera.CameraStateChanged += _camera_CameraStateChanged;

            button_Connect.Enabled = false;

            ConnectCam();

            Start();
        }

        private void _camera_CameraStateChanged(object sender, CameraStateEventArgs e)
        {
            InvokeGuiThread(() =>
            {
                if (e.State == CameraState.Connecting)
                    button_Connect.Enabled = false;
                if (e.State == CameraState.Streaming)
                    button_Disconnect.Enabled = true;
                if (e.State == CameraState.Disconnected)
                {
                    button_Disconnect.Enabled = false;
                    button_Connect.Enabled = true;
                }
            });

            InvokeGuiThread(() =>
            {
                stateLabel.Text = e.State.ToString();
            });
        }

        private void button_Disconnect_Click(object sender, EventArgs e)
        {
            if (_camera == null) return;

            _camera.Disconnect();
            _connector.Disconnect(_camera.VideoChannel, _processedImageProvider);
            _connector.Disconnect(_camera.VideoChannel, _originalImageProvider);

            _camera = null;
        }
    }
}
		

Code 1 - Motion detection example code in C#

gui of an application for barcode scanning/qr code detecting from the video stream of a usb camera in c#
Figure 1 - The graphical user interface of your application

Below you can find the code that belongs to the interface of the previously presented application. With the help of this section your Windows Forms Application will be able to work properly.

MainForm.Designer.cs

namespace MotionDetection_WF
{
    partial class MainForm
    {
        private System.ComponentModel.IContainer components = null;

        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        private void InitializeComponent()
        {
            this.label1 = new System.Windows.Forms.Label();
            this.label2 = new System.Windows.Forms.Label();
            this.tb_Threshold = new System.Windows.Forms.TextBox();
            this.label5 = new System.Windows.Forms.Label();
            this.label4 = new System.Windows.Forms.Label();
            this.groupBox2 = new System.Windows.Forms.GroupBox();
            this.rbSum = new System.Windows.Forms.RadioButton();
            this.rbAverage = new System.Windows.Forms.RadioButton();
            this.btn_HighlightSet = new System.Windows.Forms.Button();
            this.OriginalViewer = new Ozeki.Media.VideoViewerWF();
            this.ProcessedViewer = new Ozeki.Media.VideoViewerWF();
            this.groupBox5 = new System.Windows.Forms.GroupBox();
            this.stateLabel = new System.Windows.Forms.Label();
            this.label14 = new System.Windows.Forms.Label();
            this.button_Connect = new System.Windows.Forms.Button();
            this.button_Disconnect = new System.Windows.Forms.Button();
            this.tb_cameraUrl = new System.Windows.Forms.TextBox();
            this.label13 = new System.Windows.Forms.Label();
            this.button_Compose = new System.Windows.Forms.Button();
            this.groupBox2.SuspendLayout();
            this.groupBox5.SuspendLayout();
            this.SuspendLayout();

            this.label1.AutoSize = true;
            this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
            this.label1.Location = new System.Drawing.Point(7, 357);
            this.label1.Name = "label1";
            this.label1.Size = new System.Drawing.Size(87, 13);
            this.label1.TabIndex = 0;
            this.label1.Text = "Original image";

            this.label2.AutoSize = true;
            this.label2.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
            this.label2.Location = new System.Drawing.Point(357, 357);
            this.label2.Name = "label2";
            this.label2.Size = new System.Drawing.Size(103, 13);
            this.label2.TabIndex = 1;
            this.label2.Text = "Processed image";

            this.tb_Threshold.Location = new System.Drawing.Point(99, 24);
            this.tb_Threshold.Name = "tb_Threshold";
            this.tb_Threshold.Size = new System.Drawing.Size(87, 20);
            this.tb_Threshold.TabIndex = 4;

            this.label5.AutoSize = true;
            this.label5.Location = new System.Drawing.Point(6, 60);
            this.label5.Name = "label5";
            this.label5.Size = new System.Drawing.Size(78, 13);
            this.label5.TabIndex = 12;
            this.label5.Text = "Treshold Mode";
 
            this.label4.AutoSize = true;
            this.label4.Location = new System.Drawing.Point(6, 27);
            this.label4.Name = "label4";
            this.label4.Size = new System.Drawing.Size(57, 13);
            this.label4.TabIndex = 11;
            this.label4.Text = "Threshold:";

            this.groupBox2.Controls.Add(this.rbSum);
            this.groupBox2.Controls.Add(this.rbAverage);
            this.groupBox2.Controls.Add(this.label5);
            this.groupBox2.Controls.Add(this.btn_HighlightSet);
            this.groupBox2.Controls.Add(this.label4);
            this.groupBox2.Controls.Add(this.tb_Threshold);
            this.groupBox2.Location = new System.Drawing.Point(360, 12);
            this.groupBox2.Name = "groupBox2";
            this.groupBox2.Size = new System.Drawing.Size(322, 89);
            this.groupBox2.TabIndex = 13;
            this.groupBox2.TabStop = false;
            this.groupBox2.Text = "Setting";

            this.rbSum.AutoSize = true;
            this.rbSum.Location = new System.Drawing.Point(181, 58);
            this.rbSum.Name = "rbSum";
            this.rbSum.Size = new System.Drawing.Size(46, 17);
            this.rbSum.TabIndex = 21;
            this.rbSum.TabStop = true;
            this.rbSum.Text = "Sum";
            this.rbSum.UseVisualStyleBackColor = true;
 
            this.rbAverage.AutoSize = true;
            this.rbAverage.Location = new System.Drawing.Point(99, 58);
            this.rbAverage.Name = "rbAverage";
            this.rbAverage.Size = new System.Drawing.Size(65, 17);
            this.rbAverage.TabIndex = 20;
            this.rbAverage.TabStop = true;
            this.rbAverage.Text = "Average";
            this.rbAverage.UseVisualStyleBackColor = true;

            this.btn_HighlightSet.Location = new System.Drawing.Point(251, 55);
            this.btn_HighlightSet.Name = "btn_Set";
            this.btn_HighlightSet.Size = new System.Drawing.Size(58, 23);
            this.btn_HighlightSet.TabIndex = 19;
            this.btn_HighlightSet.Text = "Set";
            this.btn_HighlightSet.UseVisualStyleBackColor = true;
            this.btn_HighlightSet.Click += new System.EventHandler(this.btn_Set_Click);

            this.OriginalViewer.BackColor = System.Drawing.Color.Black;
            this.OriginalViewer.FlipMode = Ozeki.Media.FlipMode.None;
            this.OriginalViewer.FrameStretch = Ozeki.Media.FrameStretch.Uniform;
            this.OriginalViewer.FullScreenEnabled = true;
            this.OriginalViewer.Location = new System.Drawing.Point(10, 110);
            this.OriginalViewer.Name = "OriginalViewer";
            this.OriginalViewer.RotateAngle = 0;
            this.OriginalViewer.Size = new System.Drawing.Size(335, 240);
            this.OriginalViewer.TabIndex = 17;
            this.OriginalViewer.Text = "videoViewerWF1";

            this.ProcessedViewer.BackColor = System.Drawing.Color.Black;
            this.ProcessedViewer.FlipMode = Ozeki.Media.FlipMode.None;
            this.ProcessedViewer.FrameStretch = Ozeki.Media.FrameStretch.Uniform;
            this.ProcessedViewer.FullScreenEnabled = true;
            this.ProcessedViewer.Location = new System.Drawing.Point(362, 110);
            this.ProcessedViewer.Name = "ProcessedViewer";
            this.ProcessedViewer.RotateAngle = 0;
            this.ProcessedViewer.Size = new System.Drawing.Size(320, 240);
            this.ProcessedViewer.TabIndex = 18;
            this.ProcessedViewer.Text = "videoViewerWF1";

            this.groupBox5.Controls.Add(this.stateLabel);
            this.groupBox5.Controls.Add(this.label14);
            this.groupBox5.Controls.Add(this.button_Connect);
            this.groupBox5.Controls.Add(this.button_Disconnect);
            this.groupBox5.Controls.Add(this.tb_cameraUrl);
            this.groupBox5.Controls.Add(this.label13);
            this.groupBox5.Controls.Add(this.button_Compose);
            this.groupBox5.Location = new System.Drawing.Point(12, 12);
            this.groupBox5.Name = "groupBox5";
            this.groupBox5.Size = new System.Drawing.Size(333, 89);
            this.groupBox5.TabIndex = 21;
            this.groupBox5.TabStop = false;
            this.groupBox5.Text = "Connect";

            this.stateLabel.AutoSize = true;
            this.stateLabel.Location = new System.Drawing.Point(80, 72);
            this.stateLabel.Name = "stateLabel";
            this.stateLabel.Size = new System.Drawing.Size(0, 13);
            this.stateLabel.TabIndex = 24;
 
            this.label14.AutoSize = true;
            this.label14.Location = new System.Drawing.Point(39, 72);
            this.label14.Name = "label14";
            this.label14.Size = new System.Drawing.Size(35, 13);
            this.label14.TabIndex = 23;
            this.label14.Text = "State:";

            this.button_Connect.Enabled = false;
            this.button_Connect.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.5F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
            this.button_Connect.ForeColor = System.Drawing.Color.Black;
            this.button_Connect.Location = new System.Drawing.Point(83, 39);
            this.button_Connect.Name = "button_Connect";
            this.button_Connect.Size = new System.Drawing.Size(71, 23);
            this.button_Connect.TabIndex = 18;
            this.button_Connect.Text = "Connect";
            this.button_Connect.UseVisualStyleBackColor = true;
            this.button_Connect.Click += new System.EventHandler(this.button_Connect_Click);

            this.button_Disconnect.Enabled = false;
            this.button_Disconnect.Location = new System.Drawing.Point(180, 39);
            this.button_Disconnect.Name = "button_Disconnect";
            this.button_Disconnect.Size = new System.Drawing.Size(69, 23);
            this.button_Disconnect.TabIndex = 22;
            this.button_Disconnect.Text = "Disconnect";
            this.button_Disconnect.UseVisualStyleBackColor = true;
            this.button_Disconnect.Click += new System.EventHandler(this.button_Disconnect_Click);

            this.tb_cameraUrl.Location = new System.Drawing.Point(83, 13);
            this.tb_cameraUrl.Name = "tb_cameraUrl";
            this.tb_cameraUrl.ReadOnly = true;
            this.tb_cameraUrl.Size = new System.Drawing.Size(166, 20);
            this.tb_cameraUrl.TabIndex = 21;

            this.label13.AutoSize = true;
            this.label13.Location = new System.Drawing.Point(6, 16);
            this.label13.Name = "label13";
            this.label13.Size = new System.Drawing.Size(71, 13);
            this.label13.TabIndex = 20;
            this.label13.Text = "Camera URL:";

            this.button_Compose.Location = new System.Drawing.Point(255, 13);
            this.button_Compose.Name = "button_Compose";
            this.button_Compose.Size = new System.Drawing.Size(69, 23);
            this.button_Compose.TabIndex = 19;
            this.button_Compose.Text = "Compose";
            this.button_Compose.UseVisualStyleBackColor = true;
            this.button_Compose.Click += new System.EventHandler(this.button_Compose_Click);

            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(693, 380);
            this.Controls.Add(this.groupBox5);
            this.Controls.Add(this.ProcessedViewer);
            this.Controls.Add(this.OriginalViewer);
            this.Controls.Add(this.groupBox2);
            this.Controls.Add(this.label2);
            this.Controls.Add(this.label1);
            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
            this.MaximizeBox = false;
            this.Name = "MainForm";
            this.Text = "Motion Detection";
            this.Load += new System.EventHandler(this.MainForm_Load);
            this.groupBox2.ResumeLayout(false);
            this.groupBox2.PerformLayout();
            this.groupBox5.ResumeLayout(false);
            this.groupBox5.PerformLayout();
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

        private System.Windows.Forms.Label label1;
        private System.Windows.Forms.Label label2;
        private System.Windows.Forms.TextBox tb_Threshold;
        private System.Windows.Forms.Label label5;
        private System.Windows.Forms.Label label4;
        private System.Windows.Forms.GroupBox groupBox2;
        private System.Windows.Forms.Button btn_HighlightSet;
        private Ozeki.Media.VideoViewerWF OriginalViewer;
        private Ozeki.Media.VideoViewerWF ProcessedViewer;
        private System.Windows.Forms.GroupBox groupBox5;
        private System.Windows.Forms.Button button_Connect;
        private System.Windows.Forms.Button button_Disconnect;
        private System.Windows.Forms.TextBox tb_cameraUrl;
        private System.Windows.Forms.Label label13;
        private System.Windows.Forms.Button button_Compose;
        private System.Windows.Forms.Label stateLabel;
        private System.Windows.Forms.Label label14;
        private System.Windows.Forms.RadioButton rbSum;
        private System.Windows.Forms.RadioButton rbAverage;
    }
}


		

Code 2 - GUI example in C#

Conclusion

This lecture provides you detailed information on the useful motion detection function of the Ozeki Camera SDK. On this page you can find examples and implementation for setting a threshold and detect motion events in the captured video stream using your C# camera application.

Related pages

FAQ

Below you can find the answers for the most frequently asked questions related to this topic:

  1. I have not managed to build the solution. How to solve it?

    • Please set the Target framework property of the project to .NET 4.0.
    • You should add the OzekiSDK.dll to the references of the solution.
    • Please import the missing classes.
  2. What are the hardware requirements?

    • 1 GHz or faster processor
    • 1GB RAM (32-bit) || 2GB RAM (64-bit)
  3. Which OS are supported? Does it work with Windows 10?

    Yes,the SDK works with Windows 10. The following Operating Systems are supported:.

    • Microsoft Windows XP
    • Microsoft Windows Vista
    • Microsoft Windows 7
    • Microsoft Windows 8
    • Microsoft Windows 10
    • Microsoft Windows Server 2003
    • Microsoft Windows Server 2008

More information