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

Posted

技术标签:

【中文标题】无法使用 OpenCV 从辅助网络摄像头读取 VideoCapture 中的帧【英文标题】:Unable to read frames from VideoCapture from secondary webcam with OpenCV 【发布时间】:2014-03-27 23:07:14 【问题描述】:

代码:

与主网络摄像头(设备 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() 返回truecap.read(frame) 调用返回@987654329 @ 我不知道为什么。

我尝试过的:

我一直在尝试使用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");

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

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

我的硬件:HP ProBook 4510s 内置网络摄像头,始终完美运行 + 外接网络摄像头 CANYON CNR-FWCII3,被操作系统称为“USB Video Device”(麻烦的那个) 操作系统、软件:Windows 8.1 Pro x86、Visual Studio 2012 Pro、OpenCV 2.4.8 ~ 使用 vc11 构建

问题:

    我错过了什么吗? 还有什么我可以做的吗? 至少有什么方法可以检索有关问题实际可能是什么的其他信息?

... OpenCV 的 API 在这种情况下似乎很差,而且在人们似乎面临类似问题的任何地方,有人声称它是“OS / HW depnendant”作为借口。

任何帮助将不胜感激。

【问题讨论】:

当您尝试读取设备 1 时,您确定当前没有任何设备在使用它吗?也许您的程序的先前实例仍在运行? (听起来很愚蠢,但它发生在我身上!) @JamesBarnett:是的,我确定。问题是......与其猜测可能的原因,如果有一种方法可以从中获取更多信息,那就太好了。 您可以调用 cap.get(i) 并打印各种属性。这会给你一些信息see here @JamesBarnett:出于好奇,我试过read 是否总是失败,我发现这只是第一个失败的调用-_- 有趣,也许是基于时间的?因为相机还没有准备好捕捉几毫秒?如果你在第一次捕获之前休眠或循环通过一个大数组会发生什么? 【参考方案1】:

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

后来James Barnett(见上面的 cmets)指出,原因可能是相机准备好捕捉需要一段时间,而我目前的解决方案看起来如下(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();

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

【讨论】:

【参考方案2】:

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

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

// ...

【讨论】:

我正在检查原始代码中 cap.read 调用的返回值,但在我的情况下仍然不够。我认为这可能是特定于硬件/环境的。

以上是关于无法使用 OpenCV 从辅助网络摄像头读取 VideoCapture 中的帧的主要内容,如果未能解决你的问题,请参考以下文章

使用 Opencv 加速从摄像头读取视频帧

opencv能读取视频~但是无法读取摄像头,显示只有一片黑~

使用 Python/Linux 读取网络摄像头的选项

求用opencv把摄像头读取的图像转换成矩阵形式的代码

求用opencv把摄像头读取的图像转换成矩阵形式的代码

如何opencv读取摄像头并保存每一帧图像?