如何使用OpENCV解决图像处理摄像头IO延迟

How to solve image processing camera IO delay with OpenCV

本文关键字:摄像头 IO 延迟 图像处理 解决 何使用 OpENCV      更新时间:2023-10-16

我有一个像这样起作用的opencv程序:

VideoCapture cap(0);
Mat frame;
while(true) {
  cap >> frame;
  myprocess(frame);
}

问题是myprocess是否需要长时间的时间比相机的IO间隔更长,捕获的框架被延迟,无法与实时同步框架。

因此,我认为要解决这个问题,应该使摄像机流式传输和myprocess运行。一个线程进行IO操作,另一个线程进行CPU计算。相机完成捕获后,将工作线程发送到处理。

这个主意对吗?解决此问题的更好策略?

演示:

int main(int argc, char *argv[])
{
    cv::Mat buffer;
    cv::VideoCapture cap;
    std::mutex mutex;
    cap.open(0);
    std::thread product([](cv::Mat& buffer, cv::VideoCapture cap, std::mutex& mutex){
        while (true) { // keep product the new image
            cv::Mat tmp;
            cap >> tmp;
            mutex.lock();
            buffer = tmp.clone(); // copy the value
            mutex.unlock();
        }
    }, std::ref(buffer), cap, std::ref(mutex));
    product.detach();
    while (cv::waitKey(20)) { // process in the main thread
        mutex.lock();
        cv::Mat tmp = buffer.clone(); // copy the value
        mutex.unlock();
        if(!tmp.data)
            std::cout<<"null"<<std::endl;
        else {
            std::cout<<"not null"<<std::endl;
            cv::imshow("test", tmp);
        }
    }
    return 0;
}

或使用线程继续清除缓冲区。

int main(int argc, char *argv[])
{
    cv::Mat buffer;
    cv::VideoCapture cap;
    std::mutex mutex;
    cap.open(0);
    std::thread product([](cv::Mat& buffer, cv::VideoCapture cap, std::mutex& mutex){
        while (true) { // keep product the new image
            cap.grab();
        }
    }, std::ref(buffer), cap, std::ref(mutex));
    product.detach();
    int i;
    while (true) { // process in the main thread
        cv::Mat tmp;
        cap.retrieve(tmp);
        if(!tmp.data)
            std::cout<<"null"<<i++<<std::endl;
        else {
            cv::imshow("test", tmp);
        }
        if(cv::waitKey(30) >= 0) break;
    }
    return 0;
}

我认为第二个演示将是https://docs.opencv.org/3.0-beta/modules/videoio/doc/doc/reading_and_writing_video.html#videocapture-grab>

在带有多坐标跟踪的项目中,我使用了2个缓冲区(cv :: mat框架[2])和2个线程:

  1. 一个用于捕获下一帧并检测对象的线程。

  2. 第二个线程用于跟踪检测到的对象并在框架上绘制结果。

i使用index = [0,1]进行缓冲区交换,并且该索引被静音保护。用于有关工作结束的信号,使用了2个条件变量。

首先使用框架[capture_ind]缓冲区的CatureAndDetect和先前帧[1-capture_ind]缓冲区的跟踪作用。下一步 - 切换缓冲区:capture_ind = 1 -capture_ind。

您可以在此处进行此项目:Multitarget-Tracker。