Opencv запись и чтение из буфера - PullRequest
0 голосов
/ 06 февраля 2019

У меня есть две задачи (Потоки), каждая задача выполняется на другом процессоре (ядре), первая захватывает изображение несколько раз, используя 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 голосов
/ 06 февраля 2019

Как уже упоминалось, попробуйте использовать мьютекс.

Вы также можете задать условие для cv :: Mat, прежде чем пытаться его отобразить:

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

Это позволит проверить, что в отображаемом фрейме есть данные и, таким образом, избежать ошибки.

Опять же, это условие только для того, чтобы избежать ошибки imshow и не решить исходную проблему, которая, как упоминалось в других ответах, является гонкой данных между двумя потоками.

0 голосов
/ 06 февраля 2019

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();
}
0 голосов
/ 06 февраля 2019

Проблема с вашим кодом в том, что существует гонка данных. Представьте, что поток отображения сначала блокирует фрейм, и попытайтесь отобразить его до того, как он будет прочитан, чтобы вы могли увидеть проблему. Если вы хотите синхронизированное решение, вы можетеиспользуйте условие 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++;
    }

}
0 голосов
/ 06 февраля 2019
int main()
{
VideoCapture cap;
while(1){
  Mat frame;
  cap >> frame;
  imshow("frame",frame);
  waitKey();}
}

Вы можете попробовать это.Если вы пишете waitKey ();Код хочу нажать любую клавишу, чтобы получить кадр и показать кадр.

...