平台:win 10 笔记本 自带一个摄像头 再外接一个usb双目摄像头
环境:vs2015 +opencv3.4.10/opencv3.6.0
测试 代码:
int camera_test(int argc, char* argv[]) {
//【1】从摄像头读入视频//这句是关键
VideoCapture capture(0);//,cv::CAP_DSHOW, cv::CAP_MSMF or cv::CAP_V4L2.括号内数字为1是调用usb摄像头,为0则是调用电脑自带摄像头
if (!capture.isOpened()) {
cerr << "ERROR! Unable to open camera\n";
system("pause");
return -1;
}
VideoWriter writer;
//int codec = VideoWriter::fourcc('Y', 'U', 'Y', '2');//('M', 'J', 'P', 'G');capture.set(CAP_PROP_FOURCC, cv::VideoWriter::fourcc('Y', 'U', 'Y', '2'))
if (capture.set(CAP_PROP_FOURCC, cv::VideoWriter::fourcc('M', 'J', 'P', 'G'))) {
cout << "CAP_PROP_FOURCC success\n";
}
else{
cout << "CAP_PROP_FOURCC failed\n";
}
// 再次检查是否成功设置了格式
int fourcc = static_cast<int>(capture.get(cv::CAP_PROP_FOURCC));
std::cout << "当前视频编码格式: " << fourcc << std::endl;
//CAP_OPENCV_Y
int w = 3040;
int h = 1520;
//capture.set(CAP_PROP_FPS, 1);
capture.set(CAP_PROP_FRAME_WIDTH, w);//宽度
capture.set(CAP_PROP_FRAME_HEIGHT, h);//高度
//
std::cout << "当前视频长宽: " << capture.get(CAP_PROP_FRAME_WIDTH) <<" "<< capture.get(CAP_PROP_FRAME_HEIGHT) << std::endl;
std::cout << "当前视频帧率: " << capture.get(CAP_PROP_FPS) << std::endl;
//capture.set(CV_CAP_PROP_FPS, 30);//帧数
//【2】循环显示每一帧
while (1)
{
Mat frame; //定义一个Mat变量,用于存储每一帧的图像
if (!capture.read(frame)) {
cerr << "ERROR! blank frame grabbed\n";
break;
}
capture >> frame; //读取当前帧
imshow("读取视频", frame); //显示当前帧
waitKey(30); //延时30ms
}
return 0;
}
opencv3.4.10 release结果:
将【1】改为VideoCapture capture(1)打开的是外接usb摄像头,且帧率为30结果为:
CAP_PROP_FOURCC failed
当前视频编码格式: 20
当前视频长宽: 3040 1520
当前视频帧率: 30
将【1】改为VideoCapture capture(1,cv::CAP_MSMF)的结果同上
将【1】改为VideoCapture capture(1,cv::CAP_DSHOW)的结果是打开笔记本自带的摄像头而非外接usb摄像头
将【1】改为VideoCapture capture(0,cv::CAP_DSHOW)的结果是打开外接usb摄像头结果:
CAP_PROP_FOURCC success
当前视频编码格式: 1196444237
当前视频长宽: 3040 1520
当前视频帧率: 0
虽然显示,更改MJPG成功,但是输出的图像帧率极低,应该是没压缩的图像,并非MIPG格式,所以capture.set(CAP_PROP_FOURCC, cv::VideoWriter::fourcc(‘M’, ‘J’, ‘P’, ‘G’)的执行依旧是失败的
opencv3.6.0 debug结果:
将【1】改为VideoCapture capture(0)打开的是外接usb摄像头,且帧率为30结果为:
CAP_PROP_FOURCC success
当前视频编码格式: 1196444237
当前视频长宽: 3040 1520
当前视频帧率: 0
将【1】改为VideoCapture capture(0,cv::CAP_DSHOW)的结果同上
将【1】改为VideoCapture capture(0,cv::CAP_MSMF)的结果:
ERROR! Unable to open camera
请按任意键继续. . .
将【1】改为VideoCapture capture(0,cv::CAP_MSMF)的同上
**文章来源地址https://www.toymoban.com/news/detail-803498.html
结论:
1我所用的相机和opencv版本之间的兼容性存在问题,高版本的MSMF并不能使用,opencv3.4.10的MSMF可以使用
这两个版本中,DSHOW的相机id号(或camera_number就是摄像头在你电脑上的设备号,0,1,2,…)是和常规认为的是不同的。通常0是笔记本自带的相机,1是外接的相机,但实际上在我的使用中是反的,又加上opencv3.6.0的MSMF的驱动不能使用,导致在使用VideoCapture capture(1)打开相机的时候,会根据优先级尝试调用下一个驱动也就是DSHOW,从而使得在两个版本中使用VideoCapture capture(1)打开的相机是不一样的
两个版本的capture.set(CAP_PROP_FOURCC, cv::VideoWriter::fourcc(‘M’, ‘J’, ‘P’, ‘G’) 的设置都是失效的。在opencv3.3.10中,想要流畅的高帧率视频(画质低一点),就用VideoCapture capture(1,cv::CAP_MSMF),想要无压缩的高画质原图(帧率会很低),就用VideoCapture capture(0,cv::CAP_DSHOW)
解决方法:在更进一步探明并解决这个问题前,暂时使用较低版本的opencv进行开发,使用cv::CAP_MSMF/cv::CAP_DSHOW进行画质和流畅度的切换文章来源:https://www.toymoban.com/news/detail-803498.html
**
到了这里,关于OPENCV USB摄像机使用CV_MSMF与CV_DSHOW打不开的问题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!