OpenCV从缓冲区写入和读取

时间:2019-02-06 07:43:03

标签: c++ opencv video-capture

我有两个任务(线程),每个任务运行在不同的处理器(核心)上,第一个任务使用OpenCV videocapture()重复捕获图像。

我仅将这两行用于捕获:

cv::Mat frame;
capture.read(frame);

现在,我想使用第二个任务显示捕获的图像。在第二个任务的代码中执行imshow函数后:

cv::imshow("Display window", frame);

我收到以下输出错误:

OpenCV Error: Assertion failed (size.width>0 && size.height>0) in imshow, file /build/opencv-L2vuMj/opencv-3.2.0+dfsg/modules/highgui/src/window.cpp, line 304
terminate called after throwing an instance of 'cv::Exception'
what():  /build/opencv-L2vuMj/opencv-3.2.0+dfsg/modules/highgui/src/window.cpp:304: error: (-215) size.width>0 && size.height>0 in function imshow

那么,如何避免此错误?

完整的代码位于Github

4 个答案:

答案 0 :(得分:3)

cv::VideoCapture::read()返回bool,指示读取是否成功。

您正在将空的frame传递到cv::imshow()。在尝试显示之前,请尝试检查读取是否成功。

cv::Mat frame;
if(capture.read(frame))
{
    cv::imshow(frame);
}

编辑

OP发布了该代码的链接。 frame在他的程序中被声明为全局变量。在120 capture.read(frame)行中写入框架,在140 imshow(frame)行中,从frame读取而不使用互斥锁-这是数据竞争。正确的代码应遵循以下原则:

#include <mutex>
#include <opencv2/opencv.hpp>

std::mutex mutex;
cv::Mat frame;

{
    mutex.lock();
    capture.read(frame);
    mutex.unlock();
}
{
    mutex.lock();
    cv::imshow(frame);
    mutex.unlock();
}

答案 1 :(得分:2)

您的代码的问题是存在数据争用..想象一下,显示线程首先锁定框架并尝试在读取之前显示它,这样您就可以看到问题 如果您想要一个同步的解决方案,则可以使用pthread条件并等到读取图像以指示您的显示功能,否则您将处于活动等待状态!

// in the declaration part 
// Declaration of thread condition variable 
pthread_cond_t cond1 = PTHREAD_COND_INITIALIZER; 

//in the display function 

ptask DisplyingImageTask()
{

    int task_job = 0;

    while (1)
    {
        std::cout << "The job " << task_job << " of Task T" << ptask_get_index()
                  << " is running on core " << sched_getcpu() << " at time : "
                  << ptask_gettime(MILLI) << std::endl;

        cv::namedWindow("Display window", cv::WINDOW_AUTOSIZE);

        pthread_mutex_lock(&frame_rw);
        //wait for the read function to send a signal
        pthread_cond_wait(&cond1, &frame_rw);

        cv::imshow("Display window", frame);        
        cv::waitKey(1);

        pthread_mutex_unlock(&frame_rw);

        ptask_wait_for_period();
        task_job++;
    }

}

// in the Read function

ptask CapturingImageTask()
{

    int task_job = 0;

    while (1)
    {
        std::cout << "The job " << task_job << " of Task T" << ptask_get_index()
                  << " is running on core " << sched_getcpu() << " at time : "
                  << ptask_gettime(MILLI) << std::endl;

        pthread_mutex_lock(&frame_rw);
        capture.read(frame);
        //after capturing the frame signal the display function & everything should be synchronize as you want 
        pthread_cond_signal(&cond1);  

        pthread_mutex_unlock(&frame_rw);

        ptask_wait_for_period();
        task_job++;
    }

}

答案 2 :(得分:1)

int main()
{
VideoCapture cap;
while(1){
  Mat frame;
  cap >> frame;
  imshow("frame",frame);
  waitKey();}
}

您可以尝试一下。如果您编写了waitKey();代码想按任意键获取框架和显示框架。

答案 3 :(得分:1)

就像其他人提到的那样,尝试使用互斥锁。

在尝试显示它之前,您还可以在cv :: Mat上设置条件:

if (frame.data()) 
    imshow("window", frame);

这将检查要显示的帧是否有数据,从而避免错误。

再次出现这种情况只是为了避免imshow错误,而不是解决原始问题,如其他答案所述,这是两个线程之间的数据争用。