解决OpenCV-2.4.11调用摄像头显示拍摄视频出错问题

本文所用的 OpenCV 版本为 opencv-2.4.11,编程语言为 C++。

前言

  本文其实是以前在刚学 OpenCV 时遇到的一个问题,当时我的环境还是:Win7,VS2010,opencv-2.4.11。当初就记录了下来,现在再来重新梳理一下。

问题篇

问题描述:使用 OpenCV-2.4.11 调用摄像头显示拍摄视频时报 runtime error,控制台窗口出现 OpenCV Error: Assertion failed (size.width>0 && size.height>0) in cv::imshow, file ……...cpp, line 261

解决办法:在显示图片时先判断是否有图像数据,如下:

1
2
3
4
if (!image.empty()) 
{
imshow("window", image);
}

1
2
3
4
if (image.data) 
{
imshow("window", image);
}

原因可能是:用 imshow() 显示图像时,其 image 必须有数据,如果它为空则程序会报错,而一般打开摄像头会有一定时间的延迟,这时程序已经启动,而摄像头由于启动延迟,不一定能及时获取图像,造成要显示的 image 为空,因此报错。个人粗浅理解,板砖轻拍 ⊙﹏⊙b。

而网上有人也认为:

  1. 我也是遇到这个问题,不过看到一个帖子写得不错(英文的),里面给出了一个可能的理由,就是我们用 opencv 打开视频的时候,会自动先监测摄像头有没有读到帧,如果没有,就会报错,然后再执行你的程序,加一个if判断就是跳过系统自己的判断,直接执行我们的程序。来自:https://zhidao.baidu.com/question/1831122325089024420.html
  2. 有人说的原因是在 VideoCapture 刚开始获取摄像头视频流的过程不返回信号,所以判断 Mat 是否为空,并不断循环去获取 Mat。来自:http://www.cnblogs.com/tiny656/p/3538115.html

附最终完整示例程序:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <opencv2/core/core.hpp>  
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>

// 调用摄像头
void videoCaptureTest()
{
//cv::VideoCapture cap(0); // 打开默认摄像头,参数0代表默认摄像头的ID
cv::VideoCapture cap;
cap.open(0);
// 设置摄像头
cap.set(CV_CAP_PROP_FRAME_WIDTH,640);
cap.set(CV_CAP_PROP_FRAME_HEIGHT,480);
// 确认是否成功打开摄像头
if (!cap.isOpened())
{
printf("打开摄像头失败,退出!\n");
exit(-1);
}
cv::namedWindow("Capture", CV_WINDOW_AUTOSIZE|CV_WINDOW_FREERATIO);
while (1)
{
cv::Mat frame;
cap >> frame; // 获取帧

// 对摄像头获取的帧进行各种处理
if (!frame.empty()) // 最好加上该判断,并在该判断中对帧进行处理
{
cv::imshow("Capture", frame);
}
if(cv::waitKey(30) >= 0) break; // 每30ms取一帧
}
}

int main(int argc, char *argv[])
{
videoCaptureTest();

return 0;
}

  其实也可以通过在获取帧时,反复获取帧,直到取到的帧有数据为止,这样就不需要判断语句了,直接显示即可,具体代码如下:

1
2
3
4
5
6
do
{
cap >> frame;
}while(frame.empty());

cv::imshow("Capture", frame);

参考自:https://stackoverflow.com/a/9285151

后记

  本文还是当初在国内某平台写博客时写的,但现在再回头看,又稍微有了点新的思路,温故确实能知新 (*^__^*) 嘻嘻……。

参考资料

[1] OpenCV2.3使用摄像头和视频http://blog.sina.com.cn/s/articlelist_2749877462_3_1.html

[2] OpenCV Error: Assertion failed (size.width>0 && size.height>0) in cv::imshow, fi 这个问题怎么办?

[3] OpenCV打开摄像头出现运行错误OpenCV Error:Assertion failed (size.width>0&&size.height>0)in cv::imshow,……http://blog.csdn.net/czl389/article/category/6381887

[4] [OpenCV]获取摄像头视频http://www.cnblogs.com/tiny656/category/550972.html