Home > Software design >  OpenCV C# Frame Differencing
OpenCV C# Frame Differencing

Time:04-05

I'm new to computer vision and currently playing around with static frame differencing to try and determine whether there is motion in video.

My variables:

public Mat currentFrame = new Mat();
public Mat prevFrame = new Mat();
public Mat result = new Mat();
bool motion = false;

Simple differencing function (being called every frame):

public Mat getDifference(Mat videoFrame)
{
    currentFrame = videoFrame.Clone();
    Cv2.Absdiff(currentFrame, prevFrame, result);
    prevFrame = currentFrame.Clone();
    return result;
}

When motion exists the result matrix looks like this: enter image description here

When motion doesn't exist the result matrix looks like this (empty): enter image description here

My original idea was that if the result matrix is effectively empty (all black), then I could say motion = false. However, this is proving to be more difficult that anticipated since it is technically never empty, so I can't say:

if(!result.Empty())
{
    motion = true;
}

Without the need of for loops and pixel by pixel analysis, is there a simple/clean 'if' statement I can use that simply says (if the matrix contains anything that isn't black pixels, motion = true). Or... is this too simplistic? I'm open to hearing better ways of doing this, I had a look around on the web but there aren't many solid examples for C#. My video is playing within a WPF application in real-time so nested for loops are to be avoided.

Thanks for your time!

CodePudding user response:

You could for example convert the matrix to an image. That should give you access to all the image manipulation functions. For example ThresholdBinary to make pixels either zero or a given value, and CountNonZero. That should give you some tools balance how much things need to change, and how large area need to change.

CodePudding user response:

Found a simple way to do it, may not be the best but it does work.

public bool motion = false;
public Mat currentFrame = new Mat();
public Mat prevFrame = new Mat();
public Mat absDiffImage = new Mat();
public Mat grayImage = new Mat();

public Point[][] frameContours;
public HierarchyIndex[] external;
public Mat frameThresh = new Mat();

Cv2.CvtColor(currentFrame, currentFrame, ColorConversionCodes.BGRA2GRAY);
Cv2.Absdiff(currentFrame, prevFrame, absDiffImage);
Cv2.Threshold(absDiffImage, frameThresh, 80, 255, ThresholdTypes.Binary);
Cv2.FindContours(frameThresh, out frameContours, out external, RetrievalModes.List, ContourApproximationModes.ApproxSimple);

if (frameContours.Length > 20)
{
    motion = true;
}
else
{
    motion = false;
}
  • Related