Motion Detection

Jazerix picture Jazerix · Jul 13, 2013 · Viewed 19.6k times · Source

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)?

Answer

Raheel Khan picture Raheel Khan · Jul 13, 2013

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.Video.FFMPEG.VideoFileReader reader = null;
    AForge.Vision.Motion.MotionDetector motionDetector = null;    

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