我的系统通常运行100 HZ或10 ms的扫描时间并执行时间关键任务。我试图用opencv添加一次相机(取决于用户与系统交互的时间,因此它可以是从10秒暂停到分钟的任何地方)捕获图像以进行质量控制。 这是我的代码正在做的事情:
int main(int, char**)
{
VideoCapture cap(0); // open the default camera
if(!cap.isOpened()) // check if we succeeded
return -1;
UMat frame;
for(;;){
if (timing_variable_100Hz){
cap >> frame; // get a new frame from camera
*Do something time critical*
if(some_criteria_is_met){
if(!frame.empty()) imwrite( "Image.jpg", frame);
}
}
}
return 0;
}
现在我遇到的问题是cap >> frame
需要花费很多时间。
我的扫描时间通常在3毫秒左右,现在是40毫秒。现在我的问题是,无论如何打开相机,捕捉,然后不必捕捉每一帧后,直到我必须?我试图将cap >> frame
移到if(some_criteria_is_met)
内,这样我就可以正确地捕捉到第一张图像,但是几分钟后拍摄的第二张图像是第一张拍摄图像后的一帧(我希望有道理)。
谢谢
答案 0 :(得分:2)
问题是您的相机的帧速率小于100fps,可能是30fps(根据您测量的32ms),因此请等待新帧可用。
由于无法在opencv中进行非阻塞读取,我认为您最好的选择是在另一个线程中进行视频抓取。
这样的话,如果你使用c ++ 11(这是一个例子,不确定它是完全正确的):
void camera_loop(std::atomic<bool> &capture, std::atomic<bool> &stop)
{
VideoCapture cap(0);
Mat frame;
while(!stop)
{
cap.grab();
if(capture)
{
cap.retrieve(frame);
// do whatever you do with the frame
capture=false;
}
}
}
int main()
{
std::atomic<bool> capture=false, stop=false;
std::thread camera_thread(camera_loop, std::ref(capture), std::ref(stop));
for(;;)
{
// do something time critical
if(some_criteria_is_met)
{
capture=true;
}
}
stop=true;
camera_thread.join();
}
答案 1 :(得分:1)
它没有回答你are there anyway to open the camera, capture, then not have to capture every frame after until I have to?
的问题,而是一个建议
您可以尝试在后台线程中使用cap >> frame
,后台线程仅负责捕获帧。
一旦帧在内存中,将其推送到某种共享循环队列,以便从主线程访问。