VideoOperation_videoAndCamera.cpp
Upload User: whhzxy
Upload Date: 2022-01-20
Package Size: 7k
Code Size: 5k
Category:

OpenCV

Development Platform:

C/C++

  1. #include <stdio.h>
  2. #include <cv.h>
  3. #include <cxcore.h>
  4. #include <highgui.h>
  5. int main( int argc, char** argv )
  6. {
  7. //声明IplImage指针
  8. IplImage* pFrame = NULL; 
  9. IplImage* pFrImg = NULL;
  10. IplImage* pBkImg = NULL;
  11. CvMat* pFrameMat = NULL;
  12. CvMat* pFrMat = NULL;
  13. CvMat* pBkMat = NULL;
  14. // NULL 或 0 都行;
  15. CvCapture* pCapture = NULL;
  16. int nFrmNum = 0;
  17. //创建窗口
  18. cvNamedWindow("video", 1);
  19. cvNamedWindow("background",1);
  20. cvNamedWindow("foreground",1);
  21. //使窗口有序排列
  22. cvMoveWindow("video", 30, 0);
  23. cvMoveWindow("background", 360, 0);
  24. cvMoveWindow("foreground", 690, 0);
  25. if( argc > 2 )
  26. {
  27. // 另外一种在控制台中打印字符的方法,stdio.h中的函数
  28. fprintf(stderr, "Usage: bkgrd [video_file_name]n");
  29. return -1;
  30. }
  31. //有摄像头就打开摄像头,没有就打开一段默认视频;
  32. if (argc ==1)
  33. {
  34. //cvCaptureFromCAM(0) works at 90-100% cpu loading;
  35. if( pCapture = cvCaptureFromCAM(0)) //参数为0才能正常打开摄像头;
  36. {
  37. }else
  38. {
  39. // about 20%-40% loading of the CPU when use cvCreateFileCapture, or cvCaptureFromFile;
  40. // the cvCreateFileCapture and cvCaptureFromFile works as same;
  41. pCapture = cvCreateFileCapture("D:\saga\20080805-1.mpg");
  42. //pCapture = cvCaptureFromFile("D:\saga\20080805-1.mpg");
  43. //fprintf(stderr, "Can not open camera.n");
  44. //return -2;
  45. }
  46. }
  47. //打开视频文件
  48. if(argc == 2)
  49. { //实际在判断条件的时候,已经执行了;
  50. if( !(pCapture = cvCaptureFromFile(argv[1])))
  51. {
  52. fprintf(stderr, "Can not open video file %sn", argv[1]);
  53. return -2;
  54. }
  55. }
  56. //逐帧读取图像流
  57. while(pFrame = cvQueryFrame( pCapture ))
  58. {
  59. nFrmNum++;
  60. //如果是第一帧,需要申请内存,并初始化
  61. if(nFrmNum == 1)
  62. {
  63. //IplImage* cvCreateImage( CvSize size, int depth, int channels ); 
  64. //size 图像宽、高;
  65. //depth 图像元素的位深度,包括:
  66. //IPL_DEPTH_8U -  无符号8位整型 
  67. //IPL_DEPTH_8S -  有符号8位整型 
  68. //IPL_DEPTH_16U -  无符号16位整型 
  69. //IPL_DEPTH_16S -  有符号16位整型 
  70. //IPL_DEPTH_32S -  有符号32位整型 
  71. //IPL_DEPTH_32F -  单精度浮点数 
  72. //IPL_DEPTH_64F -  双精度浮点数 
  73. //channels 每个元素(像素)通道号;
  74. //可以是  1, 2, 3  或  4.通道是交叉存取的,例如通常
  75. //的彩色图像数据排列是: b0 g0 r0 b1 g1 r1 ...
  76. pBkImg = cvCreateImage(cvSize(pFrame->width, pFrame->height),  IPL_DEPTH_8U,1);
  77. pFrImg = cvCreateImage(cvSize(pFrame->width, pFrame->height),  IPL_DEPTH_8U,1);
  78. //CvMat* cvCreateMat( int rows, int cols, int type ),所以先是 height,然后是 width;
  79. //rows 矩阵行数; cols 矩阵列数; 
  80. //type 矩阵元素类型,通常以  CV_<bit_depth>(S|U|F)C<number_of_channels>型式描述
  81. //CV_8UC1   意思是一个 8-bit  无符号单通道矩阵
  82. //CV_32SC2   意思是一个32-bit  有符号二个通道的矩阵. 
  83. //S,U:有无符号整型,32F单精度浮点,64F双精度浮点
  84. pBkMat = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1);
  85. pFrMat = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1);
  86. pFrameMat = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1);
  87. //转化成单通道图像再处理
  88. cvCvtColor(pFrame, pBkImg, CV_BGR2GRAY);
  89. cvCvtColor(pFrame, pFrImg, CV_BGR2GRAY);
  90. //cvCvtColor(pFrame, pBkImg, CV_BayerGB2BGR);//bayer无法用
  91. //cvCvtColor(pFrame, pFrImg, CV_BayerGB2BGR);//bayer无法用
  92. // cvConvert( src, dst )  cvConvertScale( src, dst, scale, shift)
  93. //src 原数组   dst 输出数组  scale 比例因子  shift 原数组元素按比例缩放后添加的值
  94. //如果 scale=1, shift=0 就不会进行比例缩放
  95. //将图像转换为矩阵
  96. cvConvert(pFrImg, pFrameMat);
  97. cvConvert(pFrImg, pFrMat);
  98. cvConvert(pFrImg, pBkMat);
  99. }
  100. //如果不是第一帧
  101. else
  102. {
  103. cvCvtColor(pFrame, pFrImg, CV_BGR2GRAY);
  104. cvConvert(pFrImg, pFrameMat);
  105. //当前帧跟背景图相减,
  106. //图像的运算都是转化为多维数组的
  107. //pFrameMat - pBkMat= pFrMat
  108. cvAbsDiff(pFrameMat, pBkMat, pFrMat);
  109. //二值化前景图,cvThreshold是对数组元素进行固定阀值操作;
  110. //原始数组,输出数组,阀值,阀值最大值,
  111. cvThreshold(pFrMat, pFrImg, 30, 255.0, CV_THRESH_BINARY);
  112. //高斯滤波,平滑(模糊化)图像
  113. cvSmooth(pFrImg, pFrImg, CV_GAUSSIAN, 5, 0, 0);//模糊化frimg
  114. //cvSmooth(pFrame, pFrame, CV_GAUSSIAN, 3, 0, 0);//模糊化原图像
  115. //进行形态学滤波,去掉噪音
  116. //cvErode,使用任意结构元素腐蚀图像
  117. // 输入图像,输出图像,NULL 则是用3X3的矩形腐蚀图像,腐蚀次数;0不腐蚀
  118. cvErode(pFrImg, pFrImg, NULL, 1);
  119. //cvDilate,使用任意结构元素膨胀图像
  120. // 输入图像,输出图像,NULL/0 则是用3X3的矩形腐蚀图像,膨胀次数
  121. cvDilate(pFrImg, pFrImg, NULL, 1);
  122. //更新背景
  123. // 输入图像,累积数组,输入图像权重,可选的运算
  124. //输入图像权重(累加器以多快的速度忘掉前面的帧),变大则背景刷新速度变快,有余辉效应
  125. cvRunningAvg(pFrameMat, pBkMat, 0.05, NULL);
  126. //将背景转化为图像格式,用以显示
  127. cvConvert(pBkMat, pBkImg);
  128. //显示图像
  129. cvShowImage("video", pFrame);
  130. cvShowImage("background", pBkImg);
  131. cvShowImage("foreground", pFrImg);
  132. //如果有按键事件,则跳出循环
  133. //此等待也为cvShowImage函数提供时间完成显示
  134. //等待时间可以根据CPU速度调整
  135. if( cvWaitKey(2) >= 0 )
  136. break;
  137. }
  138. }   
  139. //销毁窗口
  140. cvDestroyWindow("video");
  141. cvDestroyWindow("background");
  142. cvDestroyWindow("foreground");
  143. //释放图像和矩阵
  144. cvReleaseImage(&pFrImg);
  145. cvReleaseImage(&pBkImg);
  146. cvReleaseMat(&pFrameMat);
  147. cvReleaseMat(&pFrMat);
  148. cvReleaseMat(&pBkMat);
  149. cvReleaseCapture(&pCapture);
  150. return 0;
  151. }