Chinaunix首页 | 论坛 | 博客
  • 博客访问: 366939
  • 博文数量: 19
  • 博客积分: 588
  • 博客等级: 中士
  • 技术积分: 317
  • 用 户 组: 普通用户
  • 注册时间: 2012-02-06 15:35
文章分类
文章存档

2012年(19)

分类: C/C++

2012-04-20 21:13:41

以前一直用OpenCV2.2.0,其实算是用的比较少了,而且比较浅。最近要用OpenCV,使用摄像头的问题,迫使自己装了OpenCV2.3.1  也不知道有没用,还没测。结果可以了。
测试代码:

点击(此处)折叠或打开

  1. #include "stdafx.h"
  2. /**************************************************
  3.  * 背景建模,运动物体检测
  4.  *
  5.  **************************************************/
  6.  
  7. /***********************************************************************
  8.  * OpenCV example
  9.  * By Shiqi Yu 2006
  10.  ***********************************************************************/
  11.  
  12.  
  13. #include <stdio.h>
  14. #include <cv.h>
  15. #include <cxcore.h>
  16. #include <highgui.h>
  17.  
  18. int main( int argc, char** argv )
  19. {
  20.   //声明IplImage指针
  21.   IplImage* pFrame = NULL;
  22.   IplImage* pFrImg = NULL;
  23.   IplImage* pBkImg = NULL;
  24.  
  25.   CvMat* pFrameMat = NULL;
  26.   CvMat* pFrMat = NULL;
  27.   CvMat* pBkMat = NULL;
  28.  
  29.   CvCapture* pCapture = NULL;
  30.  
  31.   int nFrmNum = 0;
  32.  
  33.   //创建窗口
  34.   cvNamedWindow("video", 1);
  35.   cvNamedWindow("background",1);
  36.   cvNamedWindow("foreground",1);
  37.   //使窗口有序排列
  38.   cvMoveWindow("video", 30, 0);
  39.   cvMoveWindow("background", 360, 0);
  40.   cvMoveWindow("foreground", 690, 0);
  41.  
  42.  
  43.  
  44.   if( argc > 2 )
  45.     {
  46.       fprintf(stderr, "Usage: bkgrd [video_file_name]\n");
  47.       return -1;
  48.     }
  49.  
  50.   //打开摄像头
  51.   if (argc ==1)
  52.     if( !(pCapture = cvCaptureFromCAM(-1)))
  53.       {
  54.     fprintf(stderr, "Can not open camera.\n");
  55.     return -2;
  56.       }
  57.  
  58.   //打开视频文件
  59.   if(argc == 2)
  60.     if( !(pCapture = cvCaptureFromFile(argv[1])))
  61.       {
  62.     fprintf(stderr, "Can not open video file %s\n", argv[1]);
  63.     return -2;
  64.       }
  65.  
  66.   //逐帧读取视频
  67.   while(pFrame = cvQueryFrame( pCapture ))
  68.     {
  69.       nFrmNum++;
  70.  
  71.       //如果是第一帧,需要申请内存,并初始化
  72.       if(nFrmNum == 1)
  73.     {
  74.      pBkImg = cvCreateImage(cvSize(pFrame->width, pFrame->height), IPL_DEPTH_8U,1);
  75.      pFrImg = cvCreateImage(cvSize(pFrame->width, pFrame->height), IPL_DEPTH_8U,1);
  76.  
  77.      pBkMat = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1);
  78.      pFrMat = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1);
  79.      pFrameMat = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1);
  80.  
  81.      //转化成单通道图像再处理
  82.      cvCvtColor(pFrame, pBkImg, CV_BGR2GRAY);
  83.      cvCvtColor(pFrame, pFrImg, CV_BGR2GRAY);
  84.  
  85.      cvConvert(pFrImg, pFrameMat);
  86.      cvConvert(pFrImg, pFrMat);
  87.      cvConvert(pFrImg, pBkMat);
  88.     }
  89.       else
  90.     {
  91.      cvCvtColor(pFrame, pFrImg, CV_BGR2GRAY);
  92.      cvConvert(pFrImg, pFrameMat);
  93.      //高斯滤波先,以平滑图像
  94.      //cvSmooth(pFrameMat, pFrameMat, CV_GAUSSIAN, 3, 0, 0);
  95.  
  96.      //当前帧跟背景图相减
  97.      cvAbsDiff(pFrameMat, pBkMat, pFrMat);
  98.  
  99.      //二值化前景图
  100.      cvThreshold(pFrMat, pFrImg, 60, 255.0, CV_THRESH_BINARY);
  101.  
  102.      //进行形态学滤波,去掉噪音
  103.      //cvErode(pFrImg, pFrImg, 0, 1);
  104.      //cvDilate(pFrImg, pFrImg, 0, 1);
  105.  
  106.      //更新背景
  107.      cvRunningAvg(pFrameMat, pBkMat, 0.003, 0);
  108.      //将背景转化为图像格式,用以显示
  109.      cvConvert(pBkMat, pBkImg);
  110.  
  111.      //显示图像
  112.      cvShowImage("video", pFrame);
  113.      cvShowImage("background", pBkImg);
  114.      cvShowImage("foreground", pFrImg);
  115.  
  116.      //如果有按键事件,则跳出循环
  117.      //此等待也为cvShowImage函数提供时间完成显示
  118.      //等待时间可以根据CPU速度调整
  119.      if( cvWaitKey(2) >= 0 )
  120.      break;
  121.  
  122.  
  123.     }
  124.  
  125.     }
  126.  
  127.  
  128.  
  129.  
  130.   //销毁窗口
  131.   cvDestroyWindow("video");
  132.   cvDestroyWindow("background");
  133.   cvDestroyWindow("foreground");
  134.  
  135.   //释放图像和矩阵
  136.   cvReleaseImage(&pFrImg);
  137.   cvReleaseImage(&pBkImg);
  138.  
  139.   cvReleaseMat(&pFrameMat);
  140.   cvReleaseMat(&pFrMat);
  141.   cvReleaseMat(&pBkMat);
  142.  
  143.   cvReleaseCapture(&pCapture);
  144.  
  145.   return 0;
  146. }

测试结果:win7  旗舰   vs2008   OpenCV2.3.1(用以前的OpenCV2.2.0,打开摄像头黑的,没画面)

安装OpenCV2.3.1,
link:

win7 OpenCV 问题描述:历史问题
以前Windows的摄像头和视频播放接口叫VFW,又老又丑,改成DirectShow了(刚出来的时 候叫Active Movie)。据说Windows 7 又改成了Media Foundation,没完了。 如果是无驱的,Windows只提供了DirectShow通用驱动,因此通过VFW方式无法访问。而如 果是有驱动的,那么一般来说VFW和DS是可行的。 另外,因为历史原因,DirectShow兼容传统的VFW,而VFW则不可能支持DirectShow,所以 你的摄像头即使只支持VFW,也可以用DirectShow采集,因此不存在什么DirectShow不支持 的摄像头。如果你的摄像头是无驱的,没办法,换一个有驱的。 下面说说问题的另一头:OpenCV,OpenCV 1.0的HighGUI只提供了VFW接口的摄像头支持( Windows上,Linux上则多许多),为此他还提供了一个叫cvcam的独立函数库,文档里有的 。OpenCV 计划用HighGUI支持DirectShow,以便淘汰cvcam库。期间,出现了一个叫Video Input的开源库,通过简单的C函数访问DS摄像机,并且和OpenCV配合良好,以至于OpenCV的 官网上有他的介绍。最终OpenCV 2.0纳入了VideoInput,从而让HighGUI支持了DS,但是O penCV 2.0的用法真的是…… 所以还有三个选择: cvcam VideoInput OpenCV 2.0 另外,OpenCV 1.0读取和保存AVI的接口也仅仅支持VFW,视频编解码也有VFW和DS的区分, 只支持VFW的,因此行为可能和Media Player等不同,因为目前大多数的播放器使用DS。 2.0开始用内置的FFMpeg了,支持格式较为广泛,我曾经顺利地打开rmvb和mkv,也算是一种进步。BTW,FFDShow就是DS包装下的FFMpeg。参考:

阅读(11426) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~