Ошибка подтверждения при выполнении OutputArray :: create () в потоке - PullRequest
0 голосов
/ 22 октября 2019
#include <iostream>
#include <opencv2/opencv.hpp>
#include <thread>

using namespace std;
using namespace cv;

void testThread(OutputArray image){
    image.create(100,32,CV_8U);
}
// void testThread(Mat image){
//     image.create(100,32,CV_8U);
// }
// void testThread(Mat& image){
//     image.create(100,32,CV_8U);
// }
int main(int argc,char** argv){
    Mat left= imread("./left.png",CV_8U);
    Mat right=imread("./right.png",CV_8U) ;

    thread t1(testThread,left);
    thread t2(testThread,right);
    t1.join();
    t2.join();

    // testThread(left);
    // testThread(right);

    return 0;
}

Почему он работает нормально в последовательном режиме и генерирует исключение параллельно? Также, если вы измените прототип testThread на второй, он также будет работать нормально в parllel, но потерпит неудачу для третьего. Информация об исключении, выводимая на консоль, выглядит следующим образом:

OpenCV(3.4.1) Error: Assertion failed (!fixedSize() || ((Mat*)obj)->size.operator()() == Size(_cols, _rows)) in create, file /home/linjiaqin/software/opencv-3.4.1/modules/core/src/matrix_wrap.cpp, line 1240
terminate called after throwing an instance of 'cv::Exception'
  what():  OpenCV(3.4.1) /home/linjiaqin/software/opencv-3.4.1/modules/core/src/matrix_wrap.cpp:1240: error: (-215) !fixedSize() || ((Mat*)obj)->size.operator()() == Size(_cols, _rows) in function create

1 Ответ

0 голосов
/ 22 октября 2019

У вас есть свисающая ссылка.

Класс OutputArray имеет конструктор, который принимает Mat по ссылке:

_OutputArray(Mat& m);

При создании потока вы передаете left - как Mat экземпляр. Поскольку подпись тела потока принимает OutputArray, что может принимать Mat this Mat, поскольку аргумент создается как копия. Затем OutputArray принимает этот временный объект по ссылке. Когда thread начал выполняться, OutputArray относится к уничтоженному экземпляру temp Mat (thread нужно хранить только OutputArray, без временного Mat).

Решение? Просто передайте оригинал left в OutputArray:

thread t1(testThread, OutputArray(left));
t1.join();

в вышеприведенном коде, временный экземпляр Mat не создается, поскольку копия left не создается.

...