opencv目标跟踪:三帧差分法
2016-03-22 12:11
435 查看
转载请注明转自:/article/9786837.html
网上很多opencv的帧差法资料,但是大都直接调用视频,或者调用摄像头,调用文件夹下的图片库的资料比较少,通过网上整理资料,终于利用opencv按照帧来处理图片。
使用opencv批量读取文件夹下的视频帧批量读取图片;
使用opencv批量读取图片,二帧差分法二帧差法;
具体代码如下:
参考文献:
1./article/10812600.html
2./article/4670213.html
网上很多opencv的帧差法资料,但是大都直接调用视频,或者调用摄像头,调用文件夹下的图片库的资料比较少,通过网上整理资料,终于利用opencv按照帧来处理图片。
使用opencv批量读取文件夹下的视频帧批量读取图片;
使用opencv批量读取图片,二帧差分法二帧差法;
具体代码如下:
//#include "stdAfx.h" #include <opencv2/core/core.hpp> #include <opencv2\highgui\highgui.hpp> #include <iostream> #include <direct.h>//for mk_dir #include <io.h>//for _acess() #include <opencv2/imgproc/imgproc.hpp> #define threshold_diff1 10 //设置简单帧差法阈值 #define threshold_diff2 10 //设置简单帧差法阈值 using namespace cv; using namespace std; int recursive_mkdir( char *dir );//创建多级目录 ///////三帧差分法 int main(int argc, char** argv) { ////////////////////批处理读入图片部分参数////////////////////////////// char* inputDir="F:\\论文视频库\\视频帧库\\Walking\\"; //一定要加上最后的两个双斜线,输入视频帧的目录 char* videoName="Walking.avi"; //输出的视频名字 char* outDir="F:\\论文视频库\\视频帧库\\Walking\\"; //一定要加上最后的两个双斜线,输出的视频的目录 int startFrame = 20; //含义:起始帧 int tmpFrame = startFrame; //含义:记录起始帧 int endFrame = 412; //含义:起始帧,结束帧 int imgW = 768; //含义:视频帧的宽 int imgH = 576; //含义:视频帧的高 char* imgExt = ".jpg"; //根据图片的性质选择.jpg,.bmp等类型,一定要注意jpg前面那个 //点,当时我缺了这个点,浪费了我一晚上的时间才找到问题 double fps=24; //帧率 int isColor=1; //颜色 int fourcc=CV_FOURCC('X','V','I','D'); //CV_FOURCC('X', 'V', 'I', 'D') 表示是XVID库进行压缩,压缩为MPEG4格式 IplImage *pImg=NULL; IplImage *pImg2=NULL; IplImage *pImg3=NULL; char cur_fn[255]; //表示某张图片的绝对路径 char fullVideoName[255]; //输出视频的完整文件名:路径+文件名 int frameCount = startFrame; //计算运行到第N帧 int frames = 0 ; //总帧数 CvSize size=cvSize(imgW,imgH); //////////////////////帧差法部分参数//////////////////////////////////////// Mat img_src1,img_src2,img_src3;//3帧法需要3帧图片 Mat img_dst,gray1,gray2,gray3; Mat gray_diff1,gray_diff2,gray_diff;//存储2次相减的图片 Mat gray;//用来显示前景的 //判断输入文件夹是否存在 if (_access(inputDir,0)==-1) { cout<<"the input directory does not exist!"<<endl; return 0; } //判断输出文件夹是否创建 若没有则创建;若为NULL则默认当前工作目录 strcpy_s(fullVideoName,""); if (outDir==NULL) { sprintf_s(fullVideoName,"%s",videoName);//把videoName打印成一个字符串保存在fullVideoName 中 } else { if (_access(outDir,0)==-1) { recursive_mkdir(outDir); } sprintf_s(fullVideoName,"%s%s",outDir,videoName);//将字符串outDir和videoName连接起来,打印,保存在fullVideoName中 } while(startFrame<=endFrame) { strcpy_s(cur_fn,""); sprintf_s(cur_fn,"%s%d%s",inputDir,startFrame,imgExt);//need to change pImg=cvLoadImage(cur_fn,isColor); sprintf_s(cur_fn,"%s%d%s",inputDir,startFrame-1,imgExt);//need to change pImg2=cvLoadImage(cur_fn,isColor); sprintf_s(cur_fn,"%s%d%s",inputDir,startFrame-2,imgExt);//need to change pImg3=cvLoadImage(cur_fn,isColor); if (!pImg) { std::cout<<"can't open an image file"<<std::endl; } Mat mtx(pImg); // IplImage格式转换成Mat格式 Mat mtx2(pImg2); // IplImage格式转换成Mat格式 Mat mtx3(pImg3); // IplImage格式转换成Mat格式 //为了方便使用后一帧减去前一帧: img_src3 = mtx; //当前帧 img_src2 = mtx2; //第二帧 img_src1 = mtx3; //第一帧 //img_src3;//3帧法需要3帧图片 namedWindow("MyWindow", CV_WINDOW_AUTOSIZE); imshow("MyWindow", mtx); cout<<"运行到第 "<< frameCount<<" 帧 "<<endl; waitKey(1); cvtColor(img_src1,gray1,CV_BGR2GRAY); //imshow("第一帧video_src1",img_src1);//可以事先不用新建一个窗口 //waitKey(5); cvtColor(img_src2,gray2,CV_BGR2GRAY); //imshow("第二帧video_src2",img_src2);//可以事先不用新建一个窗口 //waitKey(5); cvtColor(img_src3,gray3,CV_BGR2GRAY); //imshow("第三帧即当前帧video_src3",img_src2);//可以事先不用新建一个窗口 //waitKey(5); subtract(gray2,gray1,gray_diff1);//第二帧减第一帧 subtract(gray3,gray2,gray_diff2);//第三帧减第二帧 for(int i=0;i<gray_diff1.rows;i++) for(int j=0;j<gray_diff1.cols;j++) { if(abs(gray_diff1.at<unsigned char>(i,j))>=threshold_diff1)//这里模板参数一定要用unsigned char,否则就一直报错 gray_diff1.at<unsigned char>(i,j)=255; //第一次相减阈值处理 else gray_diff1.at<unsigned char>(i,j)=0; if(abs(gray_diff2.at<unsigned char>(i,j))>=threshold_diff2)//第二次相减阈值处理 gray_diff2.at<unsigned char>(i,j)=255; else gray_diff2.at<unsigned char>(i,j)=0; } bitwise_and(gray_diff1,gray_diff2,gray); imshow("运动目标foreground",gray); waitKey(5); Mat ero ; Mat dil ; Mat ero_dil ; Mat gaosi ; erode(gray,ero,cv::Mat()); //腐蚀 dilate(gray,dil,cv::Mat()); //膨胀 dilate(ero,ero_dil,cv::Mat()); //腐蚀后再膨胀 imshow("腐蚀后的二值图片",ero); //可以事先不用新建一个窗口 waitKey(5); imshow("膨胀后的二值图片",dil); //可以事先不用新建一个窗口 waitKey(5); imshow("腐蚀后再膨胀后的二值图片",ero_dil); //可以事先不用新建一个窗口 waitKey(5); GaussianBlur(gray,gaosi,Size(5,5),0,0); //高斯滤波 imshow("高斯滤波后的二值图片",gaosi); //可以事先不用新建一个窗口 waitKey(5); startFrame++; frameCount++; frames++; } rename(videoName,fullVideoName);//移动文件到指定文件夹 cout<<"起始帧为: "<<tmpFrame<<endl; cout<<"total frames 为: "<<frames<<" have been write to video."<<endl; system("pause"); return 0; } //该函数借鉴了网上资料,自动创建多级目录 int recursive_mkdir( char *dir ) { //分解路径名E:\\AA\\BB\\CC\\ // std::string str = dir; int index = 0; int i = 0; while(1) { std::string::size_type pos = str.find("\\",index); std::string str1; str1 = str.substr(0,pos); if( pos != -1 && i > 0 ) { if (_access(str1.c_str(),0)==-1) { _mkdir(str1.c_str()); } } if( pos==-1 ) { break; } i ++; index = pos+1; } return 0; }
参考文献:
1./article/10812600.html
2./article/4670213.html
相关文章推荐
- RTX 组织架构刷新不出来
- Nginx初步介绍
- linux下的find文件查找命令与grep文件内容查找命令
- keepalived入门之lvs高可用部署 (应用篇)
- 文本框点击和焦点时改变scrollTop值
- Linux-进程间通信(N): 各种IPC的使用场景
- 服务性能监控都包括哪些指标?
- Linux命令之tar
- Linux命令详解:[25]find常见用法示例
- linux命令:ls命令
- Centos7 常用命令
- 在CentOS7.1安装php5.6,解决PHP 5.5+ is required.
- linux 通过yum安装mysql
- opencv2.4.4 在win7 32/64位 vs2010
- Linux下的LED子系统
- tomcat
- 给自己的网站加点情趣,常用的javaScript效果
- CentOS6.7 android开发环境配置
- Hadoop/HBase下架节点
- shell脚本自动化--bond