记一次OpenCv打开摄像头失败问题的处理

最近做一个项目要用到opencv调用摄像头,遇到一个问题让折腾我一晚上才搞定,为避免有人遇到和我同样的问题,在此做个记录。

错误

问题描述:使用VideoCapture打开摄像头时,摄像头总是闪一下就关闭,查看错误信息发现有一行警告([ WARN:0] Failed to set mediaType (stream 0, (640x480 @ 30) MFVideoFormat_RGB24(unsupported media type)),大意上是告诉我媒体类型不匹配,摄像头设置失败!

网上搜了很多关于此类型的问题,都没能解决我的问题。

最后突然想到去github bug反馈那边搜了一下,还真让我搜到一丝线索,说是调用VideoCapture打开媒体文件时如果第二个参数传入cv::CAP_MSMF(capture.open(0, cv::CAP_MSMF))就有可能出现这种问题。这是该Bug链接VideoCapture fails to get frame if I use msmf and mp4 has audio stream,有兴趣可以了解下。

回头上面我遇到的错误信息,不正是MSMF类型的吗?原来VideoCapture打开摄像头默认媒体类型是CAP_MSMF,于是二话不说,直接显示传入参数capture.open(0, cv::CAP_DSHOW),搞定!

  • 30
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 18
    评论
打开摄像头的过程分为两个步骤,首先是打开摄像头设备并获取摄像头的属性,接着是从摄像头中读取图像数据。 第一步,打开摄像头设备并获取摄像头属性: 首先,需要引入opencv库并创建一个VideoCapture对象,通过指定摄像头设备的ID来打开摄像头。例如,如果要打开第一个摄像头,则设备ID为0,代码如下所示: ```c++ #include <opencv2/opencv.hpp> #include <iostream> using namespace cv; using namespace std; int main() { // 打开摄像头设备,并获取摄像头属性 VideoCapture cap(0); if (!cap.isOpened()) { // 如果无法打开摄像头设备 cout << "Error opening camera!" << endl; return -1; } // 获取摄像头图像的宽、高、帧率等属性 int width = cap.get(CAP_PROP_FRAME_WIDTH); int height = cap.get(CAP_PROP_FRAME_HEIGHT); double fps = cap.get(CAP_PROP_FPS); cout << "Camera opened successfully! Properties:" << endl; cout << "Width: " << width << " px" << endl; cout << "Height: " << height << " px" << endl; cout << "FPS: " << fps << endl; // 程序继续执行... return 0; } ``` 在上面的代码中,我们首先创建了一个VideoCapture对象cap,通过指定设备ID为0来打开第一个摄像头设备。在打开摄像头之后,我们使用cap.get()方法获取了摄像头图像的宽、高、帧率等属性,并将这些属性打印到控制台中。 第二步,从摄像头设备中读取图像数据: 接下来,我们使用cap.read()方法从摄像头设备中读取图像数据,代码如下所示: ```c++ #include <opencv2/opencv.hpp> #include <iostream> using namespace cv; using namespace std; int main() { // 打开摄像头设备,并获取摄像头属性 VideoCapture cap(0); if (!cap.isOpened()) { // 如果无法打开摄像头设备 cout << "Error opening camera!" << endl; return -1; } // 获取摄像头图像的宽、高、帧率等属性 int width = cap.get(CAP_PROP_FRAME_WIDTH); int height = cap.get(CAP_PROP_FRAME_HEIGHT); double fps = cap.get(CAP_PROP_FPS); cout << "Camera opened successfully! Properties:" << endl; cout << "Width: " << width << " px" << endl; cout << "Height: " << height << " px" << endl; cout << "FPS: " << fps << endl; // 从摄像头中读取图像数据,循环读取直到用户按下q键 while (1) { Mat frame; bool success = cap.read(frame); if (!success) { // 如果读取失败 cout << "Error reading frame from camera!" << endl; break; } imshow("Camera", frame); // 等待20ms,处理按键事件 char c = waitKey(20); if (c == 'q') { // 如果用户按下q键,则退出循环 break; } } // 释放摄像头对象 cap.release(); // 程序继续执行... return 0; } ``` 在上面的代码中,我们使用了cap.read()方法循环读取摄像头中的图像数据,并使用imshow()方法显示图像。为了让窗口可以响应按键事件,我们还使用了waitKey()方法等待用户按下按键,并判断用户是否按下了q键来退出循环。最后,在程序结束之前,我们需要调用cap.release()方法释放摄像头对象,这样才能让其他程序或进程可以访问摄像头设备。
评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值