OpenCV 4.0 -- 等待从 VideoCapture 捕获
OpenCV 4.0 -- Waiting to capture from VideoCapture
问题
我想做的是制作一个实时视频捕获 VideoCapture cap
,它只捕获每个设定的时间量 'X',其中 X 通常在 500 毫秒 - 1 秒之间。如果两次捕获 currentIMG
和 previousIMG
之间的差异足够大,则应该执行某种处理任务并将 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;
}
到目前为止我尝试了什么
- 设置缓冲区大小
cap.set(cv::CAP_PROP_BUFFERSIZE, 1)
我试过将 cap
的缓冲区大小设置为 1
,这样我就可以限制缓冲区内的图像数量。然而,尽管在打印该调用时得到了一个 1
返回,并且看起来它似乎受到支持,但它实际上并没有做任何事情来解决这个问题。
- 线程
grab()
循环
我尝试在另一个线程中使用一系列 grab()
s,主线程使用 retreive()
按照其他堆栈溢出建议,不幸的是它似乎也不起作用.有时它的行为就好像分离线程占用了缓冲区中的所有内容,以至于主线程必须等待才能从中获取一些东西。
您必须启动一个线程来抓取和检索(或简单地读取)帧,并且不允许从相机读取任何其他内容或访问 VideoCapture 对象。
该线程将最新的帧存储在某处,因此程序的其余部分可以在需要时获取该帧。
使用诸如“条件变量”之类的同步原语来向消费者发出新帧的信号,这样他们就可以等待下一个新帧,而不是可能两次获得相同的帧。这是一个 python recipe for the problem,可能不费吹灰之力就可以翻译成 C++。
问题
我想做的是制作一个实时视频捕获 VideoCapture cap
,它只捕获每个设定的时间量 'X',其中 X 通常在 500 毫秒 - 1 秒之间。如果两次捕获 currentIMG
和 previousIMG
之间的差异足够大,则应该执行某种处理任务并将 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;
}
到目前为止我尝试了什么
- 设置缓冲区大小
cap.set(cv::CAP_PROP_BUFFERSIZE, 1)
我试过将 cap
的缓冲区大小设置为 1
,这样我就可以限制缓冲区内的图像数量。然而,尽管在打印该调用时得到了一个 1
返回,并且看起来它似乎受到支持,但它实际上并没有做任何事情来解决这个问题。
- 线程
grab()
循环
我尝试在另一个线程中使用一系列 grab()
s,主线程使用 retreive()
按照其他堆栈溢出建议,不幸的是它似乎也不起作用.有时它的行为就好像分离线程占用了缓冲区中的所有内容,以至于主线程必须等待才能从中获取一些东西。
您必须启动一个线程来抓取和检索(或简单地读取)帧,并且不允许从相机读取任何其他内容或访问 VideoCapture 对象。
该线程将最新的帧存储在某处,因此程序的其余部分可以在需要时获取该帧。
使用诸如“条件变量”之类的同步原语来向消费者发出新帧的信号,这样他们就可以等待下一个新帧,而不是可能两次获得相同的帧。这是一个 python recipe for the problem,可能不费吹灰之力就可以翻译成 C++。