Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Motion Detection

I really cannot get my head around this, so I hope that someone can give me a little hand ^^

I'm trying to detect motion in C# via my webcam.

So far I've tried multiple libraries (AForge Lib), but failed because I did not understand how to use it.

At first I just wanted to compare the pixels from the current frame with the last one, but that turned out to work like utter s**t :I

Right now, my webcam runs an event "webcam_ImageCaptured" every time the picture from the webcam, which is like 5-10 fps.

But I cannot find a simple way to get the difference from the two images, or at least something that works decent.

Has anybody got an idea on how I could do this rather simple (as possible as that is)?

like image 908
Jazerix Avatar asked Jul 13 '13 00:07

Jazerix


People also ask

What is meant by motion detection?

Motion detection is the process of detecting a change in the position of an object relative to its surroundings or a change in the surroundings relative to an object. It can be achieved by either mechanical or electronic methods.

How does a motion detector work?

An active ultrasonic motion detector emits ultrasonic sound waves that reflect off objects and bounce back to the original emission point. When a moving object disrupts the waves, the sensor triggers and completes the desired action, whether this is switching on a light or sounding an alarm.

Which sensor is used for motion detection?

The most common type of active motion detector uses ultrasonic sensor technology; these motion sensors emit sound waves to detect the presence of objects. There are also microwave sensors (which emit microwave radiation), and tomographic sensors (which transmit and receive radio waves).


2 Answers

Getting motion detection to work using the libraries you mention is trivial. Following is an AForge (version 2.2.4) example. It works on a video file but you can easily adapt it to the webcam event.

Johannes' is right but I think playing around with these libraries eases the way to understanding basic image processing.

My application processes 720p video at 120FPS on a very fast machine with SSDs and around 50FPS on my development laptop.

public static void Main()
{    
    float motionLevel = 0F;
    System.Drawing.Bitmap bitmap = null;
    AForge.Vision.Motion.MotionDetector motionDetector = null;
    AForge.Video.FFMPEG.VideoFileReader reader = new AForge.Video.FFMPEG.VideoFileReader();    

    motionDetector = GetDefaultMotionDetector();

    reader.Open(@"C:\Temp.wmv");

    while (true)
    {
        bitmap = reader.ReadVideoFrame();
        if (bitmap == null) break;

        // motionLevel will indicate the amount of motion as a percentage.
        motionLevel = motionDetector.ProcessFrame(bitmap);

        // You can also access the detected motion blobs as follows:
        // ((AForge.Vision.Motion.BlobCountingObjectsProcessing) motionDetector.Processor).ObjectRectangles [i]...
    }

    reader.Close();
}

// Play around with this function to tweak results.
public static AForge.Vision.Motion.MotionDetector GetDefaultMotionDetector ()
{
    AForge.Vision.Motion.IMotionDetector detector = null;
    AForge.Vision.Motion.IMotionProcessing processor = null;
    AForge.Vision.Motion.MotionDetector motionDetector = null;

    //detector = new AForge.Vision.Motion.TwoFramesDifferenceDetector()
    //{
    //  DifferenceThreshold = 15,
    //  SuppressNoise = true
    //};

    //detector = new AForge.Vision.Motion.CustomFrameDifferenceDetector()
    //{
    //  DifferenceThreshold = 15,
    //  KeepObjectsEdges = true,
    //  SuppressNoise = true
    //};

    detector = new AForge.Vision.Motion.SimpleBackgroundModelingDetector()
    {
        DifferenceThreshold = 10,
        FramesPerBackgroundUpdate = 10,
        KeepObjectsEdges = true,
        MillisecondsPerBackgroundUpdate = 0,
        SuppressNoise = true
    };

    //processor = new AForge.Vision.Motion.GridMotionAreaProcessing()
    //{
    //  HighlightColor = System.Drawing.Color.Red,
    //  HighlightMotionGrid = true,
    //  GridWidth = 100,
    //  GridHeight = 100,
    //  MotionAmountToHighlight = 100F
    //};

    processor = new AForge.Vision.Motion.BlobCountingObjectsProcessing()
    {
        HighlightColor = System.Drawing.Color.Red,
        HighlightMotionRegions = true,
        MinObjectsHeight = 10,
        MinObjectsWidth = 10
    };

    motionDetector = new AForge.Vision.Motion.MotionDetector(detector, processor);

    return (motionDetector);
}
like image 159
Raheel Khan Avatar answered Oct 27 '22 09:10

Raheel Khan


Motion detection is a complex matter, and it requires a lot of computing power.

Try to limit what you want to detect first. With increasing complexity: Do your want to detect whether there is motion or not? Do you want to detect how much motion? Do you want to detect which areas of the image are actually moving?

I assume you just want to know when something changed:

  • subtract adjacent frames from each other
  • calc the sum of all squares of all pixel differences
  • divide by number of pixels
  • watch the number for your webcam stream. It will have a certain ground noise and will significantly go up when something moves.
  • try to limit to a certain color channel only, this may improve things
like image 1
Johannes Overmann Avatar answered Oct 27 '22 10:10

Johannes Overmann