相邻帧差法是模式识别的传统算法之一。它主要是利用时间信息,通过比较图像序列中连续的2、3帧中所有的对应位置像素点,并根据规则计算对应像素点的差值,如果差值大于一定阈值,就认为该点对应位置有运动目标存在并提取运动目标。
参考https://www.cnblogs.com/tornadomeet/archive/2012/05/01/2477629.html
编写代码如下:
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/core/core.hpp>
#define threshold_diff 20 //设置简单帧差法阈值
using namespace cv;
using namespace std;
int main(int argc,unsigned char* argv[])
{
Mat img_src1,img_src2,img_dst,gray1,gray2,gray_diff;
bool pause=false;
VideoCapture vido_file("../people.avi");//在这里改相应的文件名
namedWindow("foreground",0);
for (;;)
{
if(!pause)
{
vido_file >>img_src1; //因为视频文件帧数已经固定了,所以每次到这句语句都是读取相邻的帧数,没到时间视频并不向前走
cvtColor(img_src1,gray1,CV_BGR2GRAY);
imshow("video_src",img_src1);//可以事先不用新建一个窗口
waitKey(5);
vido_file >>img_src2;
cvtColor(img_src2,gray2,CV_BGR2GRAY);
imshow("video_src",img_src2);//可以事先不用新建一个窗口
waitKey(5);
subtract(gray1,gray2,gray_diff);
for(int i=0;i<gray_diff.rows;i++)
for(int j=0;j<gray_diff.cols;j++)
if(abs(gray_diff.at<unsigned char>(i,j))>=threshold_diff)
gray_diff.at<unsigned char>(i,j)=0;
else gray_diff.at<unsigned char>(i,j)=255;
imshow("foreground",gray_diff);
}
char c=(char)waitKey(10);
if (c==27)
{
break;
}
if(c==' ')
pause=!pause;
}
return 0;
}
处理的结果如下:
结合上一篇背景差分法的结果来看,相邻帧差法的效果并不是很好,提取出来的是前景目标的轮廓,而且轮廓的边缘比较宽,还会有重影的情况。