opencv目标跟踪:二帧差法(批量读取视频帧)(转)

原文地址:https://blog.csdn.net/ding977921830/article/details/50952683

转载请注明:http://blog.csdn.net/ding977921830/article/details/50952683

  1. //#include "stdAfx.h"
  2. #include <opencv2/core/core.hpp>
  3. #include <opencv2\highgui\highgui.hpp>
  4. #include <iostream>
  5. #include <direct.h>//for mk_dir
  6. #include <io.h>//for _acess()
  7. #include <opencv2/imgproc/imgproc.hpp>
  8. #define threshold_diff 20 //设置简单帧差法阈值
  9. using namespace cv;
  10. using namespace std;
  11. int recursive_mkdir( char *dir ); //创建多级目录
  12. int main(int argc, char** argv)
  13. { ////////////////////批处理读入图片部分参数//////////////////////////////
  14. char* inputDir= "F:\\论文视频库\\视频帧库\\Walking\\"; //一定要加上最后的两个双斜线,输入视频帧的目录
  15. char* videoName= "Walking.avi"; //输出的视频名字
  16. char* outDir= "F:\\论文视频库\\视频帧库\\Walking\\"; //一定要加上最后的两个双斜线,输出的视频的目录
  17. int startFrame = 50; //含义:起始帧
  18. int tmpFrame = startFrame; //含义:记录起始帧
  19. int endFrame = 412; //含义:起始帧,结束帧
  20. int imgW = 768; //含义:视频帧的宽
  21. int imgH = 576; //含义:视频帧的高
  22. char* imgExt = ".jpg"; //根据图片的性质选择.jpg,.bmp等类型,一定要注意jpg前面那个
  23. //点,当时我缺了这个点,浪费了我一晚上的时间才找到问题
  24. double fps= 24; //帧率
  25. int isColor= 1; //颜色
  26. int fourcc=CV_FOURCC( 'X', 'V', 'I', 'D'); //CV_FOURCC('X', 'V', 'I', 'D') 表示是XVID库进行压缩,压缩为MPEG4格式
  27. IplImage *pImg= NULL;
  28. IplImage *pImg2= NULL;
  29. char cur_fn[ 255]; //表示某张图片的绝对路径
  30. char fullVideoName[ 255]; //输出视频的完整文件名:路径+文件名
  31. int frameCount = startFrame; //计算运行到第N帧
  32. int frames = 0 ; //总帧数
  33. CvSize size=cvSize(imgW,imgH);
  34. //////////////////////帧差法部分参数////////////////////////////////////////
  35. Mat img_src1,img_src2,img_src3; //3帧法需要3帧图片
  36. Mat img_dst,gray1,gray2,gray3;
  37. Mat gray_diff1,gray_diff2,gray_diff; //存储2次相减的图片
  38. Mat gray; //用来显示前景的
  39. //判断输入文件夹是否存在
  40. if (_access(inputDir, 0)== -1)
  41. {
  42. cout<< "the input directory does not exist!"<< endl;
  43. return 0;
  44. }
  45. //判断输出文件夹是否创建 若没有则创建;若为NULL则默认当前工作目录
  46. strcpy_s(fullVideoName, "");
  47. if (outDir== NULL)
  48. {
  49. sprintf_s(fullVideoName, "%s",videoName); //把videoName打印成一个字符串保存在fullVideoName 中
  50. }
  51. else
  52. {
  53. if (_access(outDir, 0)== -1)
  54. {
  55. recursive_mkdir(outDir);
  56. }
  57. sprintf_s(fullVideoName, "%s%s",outDir,videoName); //将字符串outDir和videoName连接起来,打印,保存在fullVideoName中
  58. }
  59. // pWriter=cvCreateVideoWriter(videoName,fourcc,fps,size,isColor);//CREATE WRITER
  60. while(startFrame<=endFrame)
  61. {
  62. strcpy_s(cur_fn, "");
  63. sprintf_s(cur_fn, "%s%d%s",inputDir,startFrame,imgExt); //need to change
  64. pImg=cvLoadImage(cur_fn,isColor);
  65. sprintf_s(cur_fn, "%s%d%s",inputDir,startFrame -1,imgExt); //need to change
  66. pImg2=cvLoadImage(cur_fn,isColor);
  67. if (!pImg)
  68. {
  69. std:: cout<< "can't open an image file"<< std:: endl;
  70. }
  71. Mat mtx(pImg); // IplImage格式转换成Mat格式
  72. Mat mtx2(pImg2); // IplImage格式转换成Mat格式
  73. img_src1 = mtx;
  74. img_src2 = mtx2;
  75. //img_src3;//3帧法需要3帧图片
  76. namedWindow( "MyWindow", CV_WINDOW_AUTOSIZE);
  77. imshow( "MyWindow", mtx);
  78. cout<< "运行到第 "<< frameCount<< " 帧 "<< endl;
  79. waitKey( 1);
  80. cvtColor(img_src1,gray1,CV_BGR2GRAY);
  81. imshow( "video_src1",img_src1); //可以事先不用新建一个窗口
  82. waitKey( 5);
  83. cvtColor(img_src2,gray2,CV_BGR2GRAY);
  84. imshow( "video_src2",img_src2); //可以事先不用新建一个窗口
  85. waitKey( 5);
  86. subtract(gray1,gray2,gray_diff);
  87. for( int i= 0;i<gray_diff.rows;i++)
  88. for( int j= 0;j<gray_diff.cols;j++)
  89. if( abs(gray_diff.at< unsigned char>(i,j))>=threshold_diff) //这里模板参数一定要用unsigned char,否则就一直报错
  90. gray_diff.at< unsigned char>(i,j)= 255;
  91. else gray_diff.at< unsigned char>(i,j)= 0;
  92. imshow( "运动目标foreground",gray_diff);
  93. Mat ero ;
  94.     Mat dil ;
  95.     Mat ero_dil ;
  96.     erode(gray_diff,ero,cv::Mat());         //腐蚀
  97.     dilate(gray_diff,dil,cv::Mat());     //膨胀
  98.     dilate(ero,ero_dil,cv::Mat());         //腐蚀后再膨胀
  99.     imshow( "腐蚀后的二值图片",ero);         //可以事先不用新建一个窗口  
  100.     waitKey( 5);    
  101.     imshow( "膨胀后的二值图片",dil);         //可以事先不用新建一个窗口  
  102.     waitKey( 5);  
  103.     imshow( "腐蚀后再膨胀后的二值图片",ero_dil);         //可以事先不用新建一个窗口  
  104.     waitKey( 5); 
  105.  startFrame++;
  106. frameCount++;
  107. frames++;
  108. }
  109. rename(videoName,fullVideoName); //移动文件到指定文件夹
  110. cout<< "起始帧为: "<<tmpFrame<< endl;
  111. cout<< "total frames 为: "<<frames<< " have been write to video."<< endl;
  112. system( "pause");
  113. return 0;
  114. }
  115. //该函数借鉴了网上资料,自动创建多级目录
  116. int recursive_mkdir( char *dir )
  117. {
  118. //
  119. std:: string str = dir;
  120. int index = 0;
  121. int i = 0;
  122. while( 1)
  123. {
  124. std:: string::size_type pos = str.find( "\\",index);
  125. std:: string str1;
  126. str1 = str.substr( 0,pos);
  127. if( pos != -1 && i > 0 )
  128. {
  129. if (_access(str1.c_str(), 0)== -1)
  130. {
  131. _mkdir(str1.c_str());
  132. }
  133. }
  134. if( pos== -1 )
  135. {
  136. break;
  137. }
  138. i ++;
  139. index = pos+ 1;
  140. }
  141. return 0;
  142. }

参考文献:

1.http://blog.csdn.net/sway_2012/article/details/7786465

2.http://www.cnblogs.com/tornadomeet/archive/2012/05/01/2477629.html


猜你喜欢

转载自blog.csdn.net/zhang43211234/article/details/80952595