【发布时间】:2016-02-07 05:23:16
【问题描述】:
我正在尝试编写一个程序来同时(或几乎同时)从 2 个网络摄像头捕获图像,但有时当我运行我的程序时它会开始挂起。我的意思是它会将 FPS 降低到如此低的水平,以至于每次图像捕获之间会有 5 到 10 秒的时间。我决定制作一个更稀疏的程序,使用我认为可能导致问题的代码,这样我就可以隔离源代码。果然,我的小程序引起了问题,但我不知道是什么原因造成的。大多数情况下,它会毫无故障地运行,但有时它会在运行代码后 10 秒到 1 分钟内出现挂起的相同症状。没有出现任何错误,但从我的程序的输出来看,我确信 VideoCapture 的 grab() 正在减慢速度。
我在 OS X 中运行此程序,通过 USB 集线器使用两个外部网络摄像头,OpenCV 版本 10.4.11_1 和 C++。我不认为 USB 集线器会导致问题。坦率地说,判断它何时会冻结以及何时不会冻结是如此缓慢,以至于很难排除故障。我会摆脱 USB 集线器,但我最终需要它,而且我知道带宽不是问题。我可以运行不同 OpenCV 测试程序的多个(我已经尝试过 4 个)实例,该程序从单个摄像头捕获,所有摄像头都通过 USB 集线器连接。
我想知道 VideoCapture 类中是否有一个内部缓冲区正在填满,或者其他一些内部问题,因为我似乎无法找到有关 VideoCapture 的grab() 函数的太多文档并找出它实际占用的内容所以很长的路要走。
感谢您阅读我冗长的描述。这是我的代码:
int main(){
VideoCapture vc1(1);
VideoCapture vc2(2);
Timer tmr;
Mat img1;
Mat img2;
namedWindow("WINDOW1", CV_WINDOW_NORMAL);
namedWindow("WINDOW2", CV_WINDOW_NORMAL);
waitKey(1);
int count = 0;
while (true){
tmr.reset();
vc1.grab();
vc2.grab();
cout << "Double grab time(" << ++count << "): " << tmr.elapsed() << endl;
tmr.reset();
vc1.retrieve(img1);
vc2.retrieve(img2);
cout << "Double retrieve time: " << tmr.elapsed() << endl;
imshow("WINDOW1", img1);
imshow("WINDOW2", img2);
if (waitKey(25) == 27){
cout << "Quit" << endl;
break;
}
}
return 0;
}
使用来自 SO 帖子的这个计时器类:
class Timer
{
public:
Timer() : beg_(clock_::now()) {}
void reset() { beg_ = clock_::now(); }
double elapsed() const {
return std::chrono::duration_cast<second_>
(clock_::now() - beg_).count(); }
private:
typedef std::chrono::high_resolution_clock clock_;
typedef std::chrono::duration<double, std::ratio<1> > second_;
std::chrono::time_point<clock_> beg_;
};
并编译:
clang++ `pkg-config --libs --cflags opencv` -o test test.cpp
我无法想象我是唯一一个遇到或将遇到此问题的人,所以如果我发现任何东西,我一定会发布它。同时,我将永远感激您的帮助。
谢谢
【问题讨论】:
-
如果你
grab然后retrieve用于第一个摄像头,然后再次用于第二个摄像头,而不是同时进行grab操作,会有区别吗? -
不,问题似乎与抓取和检索操作的顺序无关。
标签: c++ opencv usb video-capture freeze