无法使用 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()
返回true
)但cap.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 中的帧的主要内容,如果未能解决你的问题,请参考以下文章