Opencv writing and reading from a buffer

左心房为你撑大大i 提交于 2019-12-12 09:54:37

问题


I have two tasks (Threads) each task runs on a different processor(core), the first capture an image repeatedly using OpenCV videocapture().

I only used these two lines for the capture :

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

Now I want to display the captured image using the second task. After executing the imshow function within the second task's code :

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

I got the following output error :

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

So, how can I avoid this error?

The complete code is hosted at Github


回答1:


The problem with your code is that there is a data race.. Imagine the display thread goes first lock the frame & try to display it before it is read so as you can see the problem If you want a synchronized solution you can use the pthread condition & wait till an image is read to signal your display function otherwise you are gonna have an active wait!!

// 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:


cv::VideoCapture::read() returns bool indicating if the read was successful or not.

You are passing an empty frame to cv::imshow(). Try checking if the read was successful before trying to show it.

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

EDIT

OP posted a link to the code. In his program frame is declared as a global variable. In line 120 capture.read(frame) writing into the frame and in line 140 imshow(frame) reads from the frame without using a mutex - that's a data race. Correct code should be along the lines of:

#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();
}



回答3:


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

You can try this. İf you write waitKey(); Code want to press any key for get frame and show frame.




回答4:


As others have mentioned try using a mutex.

You can also have a condition on the cv::Mat before trying to display it:

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

This will check that the frame to be displayed has data and thus avoiding the error.

Again this condition is only to avoid the imshow error and not to solve the original problem which, as mentioned in other answers, is a data race between the 2 threads.



来源:https://stackoverflow.com/questions/54548742/opencv-writing-and-reading-from-a-buffer

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!