win7 旗舰 vs2008 OpenCV2.3.1 解决了 OpenCV旧版本在win7下不能打开摄像头的问题 (2012-04-20 21:13)
以前一直用OpenCV2.2.0,其实算是用的比较少了,而且比较浅。最近要用OpenCV,使用摄像头的问题,迫使自己装了OpenCV2.3.1 也不知道有没用,还没测。结果可以了。
测试代码:
此处)折叠或打开
1. "stdafx.h"
2. /**************************************************
3. * 背景建模,运动物体检测
4. *
5. **************************************************/
6.
7. /***********************************************************************
8. * OpenCV example
9. * By Shiqi Yu 2006
10. ***********************************************************************/
11.
12.
13. <stdio.h>
14. <cv.h>
15. <cxcore.h>
16. <highgui.h>
17.
18. int main( int argc, char** argv )
19. {
20. //声明IplImage指针
21. * pFrame = NULL;
22. * pFrImg = NULL;
23. * pBkImg = NULL;
24.
25. * pFrameMat = NULL;
26. * pFrMat = NULL;
27. * pBkMat = NULL;
28.
29. * pCapture = NULL;
30.
31. int nFrmNum = 0;
32.
33. //创建窗口
34. ("video", 1);
35. ("background",1);
36. ("foreground",1);
37. //使窗口有序排列
38. ("video", 30, 0);
39. ("background", 360, 0);
40. ("foreground", 690, 0);
41.
42.
43.
44. if( argc > 2 )
45. {
46. (stderr, "Usage: bkgrd [video_file_name]\n");
47. -1;
48. }
49.
50. //打开摄像头
51. if (argc ==1)
52. if( !(pCapture = cvCaptureFromCAM(-1)))
53. {
54. (stderr, "Can not open camera.\n");
55. -2;
56. }
57.
58. //打开视频文件
59. if(argc == 2)
60. if( !(pCapture = cvCaptureFromFile(argv[1])))
61. {
62. (stderr, "Can not open video file %s\n", argv[1]);
63. -2;
64. }
65.
66. //逐帧读取视频
67. while(pFrame = cvQueryFrame( pCapture ))
68. {
69. ++;
70.
71. //如果是第一帧,需要申请内存,并初始化
72. if(nFrmNum == 1)
73. {
74. = cvCreateImage(cvSize(pFrame->width, pFrame->height), IPL_DEPTH_8U,1);
75. = cvCreateImage(cvSize(pFrame->width, pFrame->height), IPL_DEPTH_8U,1);
76.
77. = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1);
78. = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1);
79. = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1);
80.
81. //转化成单通道图像再处理
82. (pFrame, pBkImg, CV_BGR2GRAY);
83. (pFrame, pFrImg, CV_BGR2GRAY);
84.
85. (pFrImg, pFrameMat);
86. (pFrImg, pFrMat);
87. (pFrImg, pBkMat);
88. }
89. else
90. {
91. (pFrame, pFrImg, CV_BGR2GRAY);
92. (pFrImg, pFrameMat);
93. //高斯滤波先,以平滑图像
94. //cvSmooth(pFrameMat, pFrameMat, CV_GAUSSIAN, 3, 0, 0);
95.
96. //当前帧跟背景图相减
97. (pFrameMat, pBkMat, pFrMat);
98.
99. //二值化前景图
100. (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. (pFrameMat, pBkMat, 0.003, 0);
108. //将背景转化为图像格式,用以显示
109. (pBkMat, pBkImg);
110.
111. //显示图像
112. ("video", pFrame);
113. ("background", pBkImg);
114. ("foreground", pFrImg);
115.
116. //如果有按键事件,则跳出循环
117. //此等待也为cvShowImage函数提供时间完成显示
118. //等待时间可以根据CPU速度调整
119. if( cvWaitKey(2) >= 0 )
120. ;
121.
122.
123. }
124.
125. }
126.
127.
128.
129.
130. //销毁窗口
131. ("video");
132. ("background");
133. ("foreground");
134.
135. //释放图像和矩阵
136. (&pFrImg);
137. (&pBkImg);
138.
139. (&pFrameMat);
140. (&pFrMat);
141. (&pBkMat);
142.
143. (&pCapture);
144.
145. ;
146. }
测试结果:win7 旗舰 vs2008 OpenCV2.3.1(用以前的OpenCV2.2.0,打开摄像头黑的,没画面)
安装OpenCV2.3.1,
历史问题
以前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