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

时间:2014-02-25 15:40:00

标签: c++ opencv video usb video-capture

代码:

与主网络摄像头(设备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(0);替换VideoCapture cap(1);时,正确地打开了流(或者至少cap.isOpened()返回true但是cap.read(frame)来电回复false ,我无法找到原因。

我尝试了什么:

  • 我一直在尝试使用VideoCapture的设置,就像打电话一样:

    cap.set(CV_CAP_PROP_FORMAT, CV_8UC3);
    

    以及类似的随机内容,但似乎没有任何帮助。

  • 我也发现了这个:VideoCapture::read fails on uncompressed video (Bug #2281),这似乎是在2.4.7版本上解决的......但是我刚刚将OpenCV更新为2.4.8并且它仍然无效。 ..

  • 我尝试使用AMCap捕获此相机的原始视频,将其另存为aaa.avi文件并通过调用VideoCapture构建VideoCapture cap("aaa.avi");

    {{1}}

    它的工作原理(从文件中读取)...我需要的是实时视图的实时处理。

HW,OS,SW详细信息:

我的硬件:HP ProBook 4510s内置网络摄像头,始终完美运行 +外置网络摄像头CANYON CNR-FWCII3,操作系统称为“USB视频设备”(麻烦的) OS,SW:Windows 8.1 Pro x86,Visual Studio 2012 Pro,OpenCV 2.4.8~使用vc11 build

问题:

  1. 我错过了什么吗?
  2. 还有什么我可以做的吗?
  3. 至少是否有任何方法可以检索有关问题实际可能是什么的其他信息?
  4. ...在这种情况下,OpenCV的API似乎很差,而且在人们似乎面临类似问题的地方,有人声称它是“OS / HW depnendant”的借口。

    任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:5)

经过一段时间后,我发现始终只有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();

希望未来的访客会发现它有用:)

答案 1 :(得分:0)

最简单的解决方法是在检查成功之前阅读一次。此代码段适用于我。 //

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

// ...