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;
}
我是计算机视觉的新手,目前正在尝试使用静态帧差分来尝试确定视频中是否存在运动。
我的变量:
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;
}