无法使用OpenCV从辅助网络摄像头读取VideoCapture中的帧

Unable to read frames from VideoCapture from secondary webcam with OpenCV

本文关键字:读取 摄像头 VideoCapture 网络 OpenCV      更新时间:2023-10-16

代码:

与主要网络摄像头完美配合的简单示例(设备0):

VideoCapture cap(0);
if (!cap.isOpened()) {
std::cout << "Unable to read stream from specified device." << std::endl;
return;
}
while (true)
{
// retrieve the frame:
Mat frame;
if (!cap.read(frame)) {
std::cout << "Unable to retrieve frame from video stream." << std::endl;
break;
}
// display it:
imshow("MyVideo", frame);
// check if Esc has been pressed:
if (waitKey(1) == 27) {
break;
}
// else continue:
}
cap.release();

问题:

我有第二个网络摄像头,我想用它。但是,当我用VideoCapture cap(1);替换VideoCapture cap(0);时,流被正确打开(或者至少cap.isOpened()返回true),但cap.read(frame)调用返回false,我无法找出原因。

我尝试过的:

  • 我一直在尝试使用VideoCapture的设置,有点像调用:

    cap.set(CV_CAP_PROP_FORMAT, CV_8UC3);
    

    像这样随意的东西,但似乎没有什么帮助。

  • 我还发现:VideoCapture::在未压缩的视频上读取失败(Bug#2281),这似乎在2.4.7版本上得到了解决……但我刚刚将OpenCV更新到2.4.8,它仍然不起作用。。。

  • 我已经尝试使用AMCap从这个相机捕获原始视频,将其保存为aaa.avi文件,并通过调用:构建VideoCapture

    VideoCapture cap("aaa.avi");
    

    并且它工作(当从文件中读取时)。。。不过,我需要的是实时处理和实时视图。

硬件、操作系统、软件详细信息:

我的硬件:HP ProBook 4510s,内置网络摄像头,始终完美工作
+外部网络摄像头CANYON CNR-FWCII3,操作系统称之为"USB视频设备"(麻烦的一个)操作系统,软件:Windows 8.1 Pro x86,Visual Studio 2012 Pro,OpenCV 2.4.8~使用vc11构建

问题:

  1. 我是不是错过了什么
  2. 我还能做什么吗
  3. 是否至少有任何方法可以检索一些关于实际问题的额外信息

。。。在这种情况下,OpenCV的API似乎相当糟糕,在人们似乎面临类似问题的任何地方,都有人声称这是"OS/HW depnendant"作为借口。

任何帮助都将不胜感激。

过了一段时间,我发现总是只有read的第一次调用失败,跳过第一帧开始正常工作,尽管这种行为的真正原因仍然未知。

后来James Barnett(见上面的评论)指出,原因可能是相机需要一段时间才能准备好拍摄,而我目前的解决方案看起来如下(C++11的睡眠):

#include <chrono>
#include <thread>
...
VideoCapture cap(1);
// give camera some extra time to get ready:
std::this_thread::sleep_for(std::chrono::milliseconds(200));
if (!cap.isOpened()) {
std::cout << "Unable to read stream from specified device." << std::endl;
return;
}
while (true)
{
// retrieve the frame:
Mat frame;
if (!cap.read(frame)) {
std::cout << "Unable to retrieve frame from video stream." << std::endl;
continue;
}
// display it:
imshow("LiveStream", frame);
// stop if Esc has been pressed:
if (waitKey(1) == 27) {
break;
}
}
cap.release();

希望一些未来的访问者会发现它有帮助:)

最简单的解决方法是在检查成功之前先阅读一次。这个代码片段对我有用。//

cap.read(frame);
if(!cap.read(frame)){

//…

在我的情况下,修复方法是断开任何连接到子集线器的相机!哪怕只有一个!直接使用电脑的usb端口。