使用opencv怎么解析三帧差法?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。
#include<iostream>
#include<opencv2\core\core.hpp>
#include<opencv2\highgui\highgui.hpp>
#include<opencv2\imgproc\imgproc.hpp>
using namespace cv;
using namespace std;
const unsigned char FORE_GROUD = 255;int thresh = 10;
int main(int argc,char*argv[])
{
VideoCapture video(argv[1]); //判断如果video是否可以打开
if(!video.isOpened())
return -1;
//用于保存当前帧的图片
Mat currentBGRFrame;
//用来保存上一帧和当前帧的灰度图片
Mat previousSecondGrayFrame; Mat previousFirstGrayFrame; Mat currentGaryFrame;
//保存两次的帧差
Mat previousFrameDifference; //previousFrameFirst - previousFrameSecond的差分
Mat currentFrameDifference; //currentFrame - previousFrameFirst;
//用来保存帧差的绝对值
Mat absFrameDifferece;
//用来显示前景
Mat previousSegmentation; Mat currentSegmentation; Mat segmentation;
//显示前景
namedWindow("segmentation",1);
createTrackbar("阈值:","segmentation",&thresh,FORE_GROUD,NULL);
//帧数
int numberFrame = 0;
//形态学处理用到的算子
Mat morphologyKernel = getStructuringElement(MORPH_RECT,Size(3,3),Point(-1,-1));
for(;;)
{ //读取当前帧
video >> currentBGRFrame;
//判断当前帧是否存在
if(!currentBGRFrame.data)
break;
numberFrame++;
//颜色空间的转换
cvtColor(currentBGRFrame,currentGaryFrame,COLOR_BGR2GRAY);
if( numberFrame == 1) {
//保存当前帧的灰度图
previousSecondGrayFrame = currentGaryFrame.clone();
//显示视频
imshow("video",currentBGRFrame); continue; }
else if( numberFrame == 2)
{
//保存当前帧的灰度图
previousFirstGrayFrame = currentGaryFrame.clone();
//previousFirst - previousSecond
subtract(previousFirstGrayFrame,previousSecondGrayFrame,previousFrameDifference,Mat(),CV_16SC1);
//取绝对值
absFrameDifferece = abs(previousFrameDifference);
//位深的改变
absFrameDifferece.convertTo(absFrameDifferece,CV_8UC1,1,0);
//阈值处理
threshold(absFrameDifferece,previousSegmentation,double(thresh),double(FORE_GROUD),THRESH_BINARY);
//显示视频
imshow("video",currentBGRFrame);
continue; }
else
{
//src1-src2
subtract(currentGaryFrame,previousFirstGrayFrame,currentFrameDifference,Mat(),CV_16SC1);
//取绝对值
absFrameDifferece = abs(currentFrameDifference);
//位深的改变 absFrameDifferece.convertTo(absFrameDifferece,CV_8UC1,1,0);
//阈值处理
threshold(absFrameDifferece,currentSegmentation,double(thresh),double(FORE_GROUD),THRESH_BINARY); //与运算
bitwise_and(previousSegmentation,currentSegmentation,segmentation); //中值滤波
medianBlur(segmentation,segmentation,3); //形态学处理(开闭运算)
//morphologyEx(segmentation,segmentation,MORPH_OPEN,morphologyKernel,Point(-1,-1),1,BORDER_REPLICATE);
morphologyEx(segmentation,segmentation,MORPH_CLOSE,morphologyKernel,Point(-1,-1),2,BORDER_REPLICATE);
//找边界
vector< vector<oint> > contours;
vector<Vec4i> hierarchy;
//复制segmentation
Mat tempSegmentation = segmentation.clone();
findContours( segmentation, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, Point(0, 0) );//CV_RETR_TREE
vector< vector<oint> > contours_poly( contours.size() );
/*存储运动物体*/
vector<Rect> boundRect;
boundRect.clear();
//画出运动物体
for(int index = 0;index < contours.size() ;index++)
{
approxPolyDP( Mat(contours[index]), contours_poly[index], 3, true );
Rect rect = boundingRect( Mat(contours_poly[index]) );
rectangle(currentBGRFrame,rect,Scalar(0,255,255),2); }
//显示视频
imshow("video",currentBGRFrame);
//前景检测
imshow("segmentation",segmentation);
//保存当前帧的灰度图
previousFirstGrayFrame = currentGaryFrame.clone();
//保存当前的前景检测
previousSegmentation = currentSegmentation.clone();
}
if(waitKey(33) == 'q')
break;
}
return 0;
}
看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注亿速云行业资讯频道,感谢您对亿速云的支持。
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。