简体   繁体   English

一次捕捉相机相框

[英]Capturing camera frames once a while

I have a system that is typically running a scan time of 100 HZ or 10 ms and performing time critical tasks. 我的系统通常运行100 HZ或10 ms的扫描时间并执行时间关键任务。 I'm trying to add a camera with opencv to once a while (depends on when a user interacts with the system so it can be anywhere from 10 seconds pauses to minutes) capture an image for quality control. 我试图用opencv添加一次相机(取决于用户与系统交互的时间,因此它可以是从10秒暂停到分钟的任何地方)捕获图像以进行质量控制。 Here is what my code is doing: 这是我的代码正在做的事情:

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;
}

Now the issue I'm having is that cap >> frame takes a lot of time. 现在我遇到的问题是cap >> frame需要花费很多时间。

My scan time regularly runs around 3ms and now it's at 40ms. 我的扫描时间通常在3毫秒左右,现在是40毫秒。 Now my question is, are there anyway to open the camera, capture, then not have to capture every frame after until I have to? 现在我的问题是,无论如何打开相机,捕捉,然后不必捕捉每一帧后,直到我必须? I tried to move the cap >> frame inside the if(some_criteria_is_met) which allowed me to capture the first image correctly but the second image which was taken a few minutes later was a single frame past the first captured image (I hope that makes sense). 我试图在if(some_criteria_is_met)移动cap >> frame ,这允许我正确地捕获第一个图像,但几分钟后拍摄的第二个图像是第一个捕获图像之后的一帧(我希望这是有道理的) )。

Thanks 谢谢

The problem is that your camera has a framerate of less than 100fps, probably 30fps (according to the 32ms you measured), so grab wait for a new frame to be available. 问题是您的相机的帧速率小于100fps,可能是30fps(根据您测量的32ms),因此请等待新帧可用。

Since there is no way to do a non blocking read in opencv, i think that your best option is to do the video grabbing in another thread. 由于无法在opencv中执行非阻塞读取,我认为您最好的选择是在另一个线程中执行视频抓取。

Something like this, if you use c++11 (this is an example, not sure it is entirely correct): 像这样的东西,如果你使用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();
}

It doesn't answer your question of are there anyway to open the camera, capture, then not have to capture every frame after until I have to? 它没有回答你的问题, are there anyway to open the camera, capture, then not have to capture every frame after until I have to? , but a suggestion ,但一个建议

You could try and have the cap >> frame in a background thread which is responsible only for capturing the frames. 您可以尝试在后台线程中使用cap >> frame ,后者仅负责捕获帧。

Once the frame is in memory, push it to some sort of shared cyclic queue to be accessed from the main thread. 一旦帧在内存中,将其推送到某种共享循环队列,以便从主线程访问。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM