如何防止在opencv中缓冲图像

时间:2018-01-19 19:24:26

标签: opencv

假设我们在opencv中有一个进程,当我们调用此函数时,它的名称为process,大约需要2秒才能在一帧上完成。  如果我们在opencv中使用Videocapture方法捕获帧,则帧存储在缓冲区中,当process完成第n帧上的过程时,它会抓住下一帧(( n + 1)th frame)但是我想在真实时刻抓住帧而不是属于过去的帧...例如你可以在下面测试示例

Mat frame;
VideoCapture cap(0);
while (true) {
    cap.read(frame);
    imshow("s",frame);
    waitKey(2000);     //artificial delay
}

如果您在上面的示例中运行,您会看到显示的帧属于过去而非当前时刻。那么我的问题是如何跳过这些帧?

1 个答案:

答案 0 :(得分:1)

  • 新方法

只需在OpenCV中启动videoCapture后就可以使用以下功能了。

videoCapture cap(0);
cap.set(CV_CAP_PROP_BUFFERSIZE, 1); //now the opencv buffer just one frame.
  • 使用线程

我通过使用多线程编程完成了任务。请问这个问题的重点是什么!! ??答案是当你使用像raspberrypi这样的弱处理器或者你有一个需要一些时间来完成一项任务的大算法时,你可能会遇到这个问题并且你看到你的帧中存在很大的延迟。

我通过使用Qt类来解决Qtconcurrent中的这个问题,该类能够轻松地运行线程并减少编码。我们的想法是我们将主线程作为处理单元运行并运行一个线程来连续捕获帧,当主线程在一个特定帧上完成处理时,它会从第二个线程询问另一个帧!并且在第二个线程中无延迟地捕获帧非常重要。 所以非常明显的是,如果处理单元需要2秒钟,而另一方面捕获帧需要0.2秒,那么我们会丢失中间帧。

我附上我的项目如下

<强> 1.main.cpp

#include <opencv2/opencv.hpp>
#include <new_thread.h>     //this is a custom class that required for grab frames(we dedicate a new thread for this class)
#include <QtConcurrent/QtConcurrent>    
using namespace cv;
#include <QThread>     //need for generate artificial delay, which in real situation it will produce by weak processor or etc. 
int main()
{
      Mat frame;
      new_thread th;       //create an object from new_thread class
      QtConcurrent::run(&th,&new_thread::get_frame);   //start a thread with QtConcurrent
      QThread::msleep(2000); //need some time to start(open) camera
      while(true)
      {
          frame=th.return_frame();
          imshow("frame",frame);
          waitKey(20);
          QThread::msleep(2000); //artifical delay, or a big process
      }
}  

<强> 2.new_thread.h

#include <opencv2/opencv.hpp>
using namespace cv;
class new_thread
{
public:
    new_thread();             //constructor
    void get_frame(void);     //grab frame
    Mat return_frame();       //return frame to main.cpp
private:
    VideoCapture cap;         
    Mat frame;               //frmae i
};

<强> 3.new_thread.cpp

#include <new_thread.h>
#include <QThread>
new_thread::new_thread()
{
    cap.open(0);        //open camera when class is constructing
}

void new_thread::get_frame()       //get frame method 
{
    while(1)                     // while(1) because we want to grab frames continuously 
    {
        cap.read(frame);
    }
}

Mat new_thread::return_frame()
{
    return frame;              //whenever main.cpp need updated frame it can request last frame by usign this method
}