Looking for a function for motion detection on emgucv

故事扮演 提交于 2019-12-02 08:34:58

问题


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?


回答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);
       }



回答2:


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.



来源:https://stackoverflow.com/questions/12580453/looking-for-a-function-for-motion-detection-on-emgucv

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!