我知道标题有点模糊,但我不确定如何形容它.
CentOS与ffmpeg OpenCV 2.4.9.我正在研究一种简单的运动检测系统,该系统使用来自IP摄像机的流(h264).
偶尔流会打嗝并抛出“坏帧”(参见下面的pic-bad.png链接).问题是,这些帧在很大程度上与先前帧不同,并且即使没有发生实际运动也会导致“运动”事件被触发.
下面的图片将解释这个问题.
好框架(动作捕捉):
坏帧(没有动作,只是一个破帧):
坏帧被随机捕获.我想我可以通过分析(循环)通过从某个位置向下的像素来制作一个糟糕的帧检测器,看看它们是否完全相同,但我想知道是否还有其他的,更有效的,“这本书“检测这些类型的坏帧并跳过它们的方法.
谢谢!
编辑更新:
通过cvQueryFrame(相机)使用C运动检测程序抓取帧;所以我不直接与ffmpeg接口,OpenCV在后端做它.我正在使用从git源编译的最新版本的ffmpeg.所有的库都是最新的(h264等,都是昨天下载和编译的).数据来自RTSP流(ffserver).我已经测试了多个摄像头(大华1 – 3 MP型号),并且帧毛刺在所有这些都非常持久,尽管它不是连续发生的,只是偶尔发生一次(例如:每10分钟一次).
解决方法
在第一种方法中我想到的是通过计算不同的像素来检查有效帧的示例与我们正在检查的示例之间的不相似性.将这个数除以面积,我们得到衡量不相似度的百分比.我猜大于0.5,我们可以说测试帧是无效的,因为它与有效帧的例子有很大不同.
这个假设只适用于你有一个静态相机(它不移动),并且可以在它前面移动的物体不在最短距离内(取决于焦距,但如果你有例如宽镜头那么物体不应该在相机前方出现不到30厘米,以防止物体从不知名的地方“跳入”框架并且其尺寸大于框架区域的50%).
在这里你有opencv功能,它做我说的.实际上,如果您认为运动变化会更快,您可以将相似系数调整得更大.请注意,第一个参数应该是有效帧的示例.
bool IsBadFrame(const cv::Mat &goodFrame,const cv::Mat &nextFrame) { // assert(goodFrame.size() == nextFrame.size()) cv::Mat g,g2; cv::cvtColor(goodFrame,g,CV_BGR2GRAY); cv::cvtColor(nextFrame,g2,CV_BGR2GRAY); cv::Mat diff = g2 != g; float similarity = (float)cv::countNonZero(diff) / (goodFrame.size().height * goodFrame.size().width); return similarity > 0.5f; }