一次捕捉相机相框

时间:2016-05-26 08:05:56

标签: c++ opencv

我的系统通常运行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)内,这样我就可以正确地捕捉到第一张图像,但是几分钟后拍摄的第二张图像是第一张拍摄图像后的一帧(我希望有道理)。

谢谢

2 个答案:

答案 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,后台线程仅负责捕获帧。

一旦帧在内存中,将其推送到某种共享循环队列,以便从主线程访问。