Looking for a function for motion detection on emgucv
Asked Answered
O

2

1

I am new to emgu cv; I'm trying to find a code that makes motion detection. I tried this:

CvInvoke.cvAbsDiff(frame, _backgroundImage, BgDifference);

... but I have lighting problems. I want to get white the pixels where there was motion, and then draw a rectangle there only one rectangle, but I take more areas with white pixels.

What do I need to do? Could I try ananother function?

Observe answered 25/9, 2012 at 9:51 Comment(1)
You may use the code of my answer at this link: #23582884Maharaja
M
1

Convert a single frame to grayscale. Convert a new frames from real time into grayscale. Make abstractions between the first frame and new frame from real time. The result of this is a third, new frame comprised of the differences between the first two. Use erosion and thresholding for that to get a frame with white representing the motioned section and black representing the rest of the space.

Here is a piece of code:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Emgu.CV;
using Emgu.CV.UI;
using Emgu.CV.CvEnum;
using Emgu.CV.Structure;
using System.Diagnostics;
using System.IO;
using System.Data.SqlClient;
using System.Data.SqlServerCe;
using System.Drawing.Imaging;

namespace ptuxiakh___
{
    public partial class Form1 : Form
    {
        Capture _capture = new Capture();
        Capture capture2 = new Capture();

        Image<Bgr, Byte> FirstImage = new Image<Bgr, Byte>(640, 480);
        Image<Bgr, Byte> RealTimeImage = new Image<Bgr, Byte>(640, 480);

        Image<Gray, Byte> des = new Image<Gray, Byte>(640, 480);
        Image<Gray, Byte> thres = new Image<Gray, Byte>(640, 480);
        Image<Gray, Byte> eroded = new Image<Gray, Byte>(640, 480);

        bool baground = false;

        private void Background()
        {
            try
            {
                FirstImage = _capture.QueryFrame();
                background = true;
            }
            catch(Exception e)
            {
                baground = false;
            }
        }

        private void Tracking(object sender, EventArgs e)
        {
            if (baground == true)
            {
                RealTimeImage   = capture2.QueryFrame();

                CvInvoke.cvAbsDiff(FirstImage.Convert<Gray, Byte>(),
                    RealTimeImage.Convert<Gray, Byte>(), des);
                CvInvoke.cvThreshold(des, thres, 20, 255, THRESH.CV_THRESH_BINARY);
                CvInvoke.cvErode(thres, eroded, IntPtr.Zero, 2);
            }
            else
            {
                Background(); // At first trying to get a static frame for 
                        // abstraction with real time frame 
            }
       }

       private void StartButton_Click(object sender, EventArgs e)
       {
           Application.Idle += new EventHandler(Tracking);
       }

       private void Stopbutton_Click(object sender, EventArgs e)
       {
           Application.Idle -= new EventHandler(Tracking);
       }
Maharaja answered 3/7, 2014 at 9:19 Comment(0)
I
1

You can use the MotionHistory class. EmguCV includes an motion detection example (if it doesn't anymore, you can see it here ). With this class, you can get an motionImage, and then you only need to count the pixels to check the biggest area.

Investment answered 23/8, 2013 at 13:3 Comment(1)
I got into a DLL nightmare using the sample linked to (see https://mcmap.net/q/1633504/-getting-emgu-cv-motion-detection-sample-working-unable-to-load-dll-39-opencv_legacy249-39 ). So do check the installation directory first (e.g. C:\Emgu\emgucv-windows-universal-gpu 2.4.9.1847\Emgu.CV.Example\MotionDetection ) or the code repository: sourceforge.net/p/emgucv/code/ci/master/tree/Emgu.CV.Example/…Drogheda
M
1

Convert a single frame to grayscale. Convert a new frames from real time into grayscale. Make abstractions between the first frame and new frame from real time. The result of this is a third, new frame comprised of the differences between the first two. Use erosion and thresholding for that to get a frame with white representing the motioned section and black representing the rest of the space.

Here is a piece of code:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Emgu.CV;
using Emgu.CV.UI;
using Emgu.CV.CvEnum;
using Emgu.CV.Structure;
using System.Diagnostics;
using System.IO;
using System.Data.SqlClient;
using System.Data.SqlServerCe;
using System.Drawing.Imaging;

namespace ptuxiakh___
{
    public partial class Form1 : Form
    {
        Capture _capture = new Capture();
        Capture capture2 = new Capture();

        Image<Bgr, Byte> FirstImage = new Image<Bgr, Byte>(640, 480);
        Image<Bgr, Byte> RealTimeImage = new Image<Bgr, Byte>(640, 480);

        Image<Gray, Byte> des = new Image<Gray, Byte>(640, 480);
        Image<Gray, Byte> thres = new Image<Gray, Byte>(640, 480);
        Image<Gray, Byte> eroded = new Image<Gray, Byte>(640, 480);

        bool baground = false;

        private void Background()
        {
            try
            {
                FirstImage = _capture.QueryFrame();
                background = true;
            }
            catch(Exception e)
            {
                baground = false;
            }
        }

        private void Tracking(object sender, EventArgs e)
        {
            if (baground == true)
            {
                RealTimeImage   = capture2.QueryFrame();

                CvInvoke.cvAbsDiff(FirstImage.Convert<Gray, Byte>(),
                    RealTimeImage.Convert<Gray, Byte>(), des);
                CvInvoke.cvThreshold(des, thres, 20, 255, THRESH.CV_THRESH_BINARY);
                CvInvoke.cvErode(thres, eroded, IntPtr.Zero, 2);
            }
            else
            {
                Background(); // At first trying to get a static frame for 
                        // abstraction with real time frame 
            }
       }

       private void StartButton_Click(object sender, EventArgs e)
       {
           Application.Idle += new EventHandler(Tracking);
       }

       private void Stopbutton_Click(object sender, EventArgs e)
       {
           Application.Idle -= new EventHandler(Tracking);
       }
Maharaja answered 3/7, 2014 at 9:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.