OPENCV USB摄像机使用CV_MSMF与CV_DSHOW打不开的问题

平台: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)的同上

**

结论:

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进行画质和流畅度的切换

**

  • 26
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值