OpenCV 4.0 -- 等待从 VideoCapture 捕获

OpenCV 4.0 -- Waiting to capture from VideoCapture

问题

我想做的是制作一个实时视频捕获 VideoCapture cap,它只捕获每个设定的时间量 'X',其中 X 通常在 500 毫秒 - 1 秒之间。如果两次捕获 currentIMGpreviousIMG 之间的差异足够大,则应该执行某种处理任务并将 previousIMG 设置为刚刚捕获的那个,这样它就会它比较了从那一点开始的捕获。

然而,在尝试这样做时,我注意到 它实际上并没有得到相机在醒来时看到的内容。据我所知,它只是得到了 VideoCapture 对象的“缓冲区中的下一个”。这导致它只是在获取缓冲区中的下一个内容之前暂停,而不是跳过它在这两个时间段之间看到的所有内容。

有没有一种节省时间的方法来确保我在醒来时得到“相机看到”的任何东西,而不仅仅是接下来缓冲区中的任何东西?

使用的代码

int main() {

    // open the camera and capture a image
    Mat currentIMG, previousIMG;
    VideoCapture cap;
    cap >> previousIMG;

    struct timespec ts = {ts.tv_sec = 1, ts.tv_nsec = 0};
    for (;;) {
        
        // wait & then capture an image for 'currentIMG'
        nanosleep(&ts, NULL);
        cap >> currentIMG;

        // check if the difference between the previous
        // and current images (in terms of decimal percentage)
        // exceeds the threshold 
        if (PSNR(currentIMG, previousIMG) > 0.20) {
    
            // Some kind of task that takes a bit to complete
            imwrite("capturedIMG.png", currentIMG);
            previousIMG = currentIMG.clone();
        }
    }

    // Exit
    return 0;
}

到目前为止我尝试了什么

  1. 设置缓冲区大小 cap.set(cv::CAP_PROP_BUFFERSIZE, 1)

我试过将 cap 的缓冲区大小设置为 1,这样我就可以限制缓冲区内的图像数量。然而,尽管在打印该调用时得到了一个 1 返回,并且看起来它似乎受到支持,但它实际上并没有做任何事情来解决这个问题。

  1. 线程grab()循环

我尝试在另一个线程中使用一系列 grab()s,主线程使用 retreive() 按照其他堆栈溢出建议,不幸的是它似乎也不起作用.有时它的行为就好像分离线程占用了缓冲区中的所有内容,以至于主线程必须等待才能从中获取一些东西。

您必须启动一个线程来抓取和检索(或简单地读取)帧,并且不允许从相机读取任何其他内容或访问 VideoCapture 对象。

该线程将最新的帧存储在某处,因此程序的其余部分可以在需要时获取该帧。

使用诸如“条件变量”之类的同步原语来向消费者发出新帧的信号,这样他们就可以等待下一个新帧,而不是可能两次获得相同的帧。这是一个 python recipe for the problem,可能不费吹灰之力就可以翻译成 C++。