OpenCV C# 帧差分

OpenCV C# Frame Differencing

我是计算机视觉的新手,目前正在尝试使用静态帧差分来尝试确定视频中是否存在运动。

我的变量:

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

简单差分函数(每帧调用):

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

当运动存在时,结果矩阵如下所示:

当运动不存在时,结果矩阵如下所示(空):

我最初的想法是,如果结果矩阵实际上是空的(全黑),那么我可以说 motion = false。然而,事实证明这比预期的要困难,因为它在技术上永远不会是空的,所以我不能说:

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

不需要 for 循环和逐像素分析,是否有一个 simple/clean 'if' 语句我可以使用它简单地说(如果矩阵包含任何不是黑色像素的东西,运动 = 真)。还是……这太简单了?我很乐意听到更好的方法来做到这一点,我在网上四处看看,但 C# 的可靠示例并不多。我的视频在 WPF 应用程序中实时播放,因此要避免嵌套 for 循环。

感谢您的宝贵时间!

例如,您可以将矩阵转换为图像。这应该可以让您访问所有图像处理功能。例如 ThresholdBinary 使像素为零或给定值,以及 CountNonZero。那应该给你一些工具来平衡需要改变多少东西,以及需要改变多大的区域。

找到了一个简单的方法,可能不是最好的,但确实有效。

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