【问题标题】:Assertion failed (size.width>0 && size.height>0) in imshow after copying image复制图像后,imshow 中的断言失败(size.width>0 && size.height>0)
【发布时间】:2014-05-11 00:19:48
【问题描述】:

我有一个问题,我试图在不同的线程上显示两个图像,其中两个图像都来自同一帧,但其中一个是原始帧的副本,另一个是原始帧。该程序将能够完美地显示原始帧,但是当带有克隆/复制图像的线程到达 imshow() 时,它会崩溃并显示错误:“断言失败 (size.width>0 && size.height>0) in imshow ”。

有人可以帮忙吗? 问候。

这是获取相机输入的类:

CameraInput::CameraInput()
{
// Initialize capturing live feed from the camera
capture.open(0);
capture.set(CV_CAP_PROP_FRAME_WIDTH, 640);
capture.set(CV_CAP_PROP_FRAME_HEIGHT, 480);

 // Couldn't get a device? Throw an error and quit
if(!capture.isOpened())
 {
    qDebug() << "Capture could not be opened successfully.";
 }
 qDebug() << "Capure =" << QThread::currentThreadId();
}

void CameraInput::captureImage()
{
capture >> frame;

if(!frame.empty())
{
    emit capturedImage(&frame);
}
//qDebug() << "capture" << QThread::currentThreadId();
}

这是到达“emit captureImage(&Frame);”时运行的函数。这很好用。

void Controll::inputImage(cv::Mat* imgIn)
{
cv::imshow("video", *imgIn);
if (processReady) 
{
    processReady = false;
    emit image(imgIn);
}

emit requestImage();

// see how much time has elapsed
time(&end);

// calculate current FPS
++counterOrg;
sec = difftime (end, start);

fpsOrg = counterOrg / sec;

// will print out Inf until sec is greater than 0
printf("FPS Org stream = %.2f\n", fpsOrg);

}

这是到达“emit image(imgIn);”时调用的函数。

void Process::processImage(cv::Mat* img)
{
cv::Mat imgHSV = img->clone();
emit (processedImage(&imgHSV));
emit (readyForWork());
}

在下面的代码中,我们遇到了一个错误,打印了调试行,但是在 imshow() 上我们得到了提到的错误。我们也尝试过使用复制构造函数和 copyTo(),都产生了相同的结果。

void Controll::processedImage(cv::Mat* imgIn)
{
qDebug() << "About to show thresh image...";
cv::imshow("thresh", *imgIn);
// see how much time has elapsed
time(&end);

// calculate current FPS
++counterProcessed;
sec = difftime (end, start);

fpsProcessed = counterProcessed / sec;

// will print out Inf until sec is greater than 0
printf("FPS processed stream = %.2f\n", fpsProcessed);
}

这是main.cpp:

int main()
{
int c;

// Objects
CameraInput *camera = new CameraInput();
Controll *troller = new Controll();
Process *processer = new Process();
Tracking *tracker = new Tracking();
Serial_Communication *serial = new Serial_Communication("/dev/ttyUSB0");

// Threads
QThread *t1 = new QThread;
QThread *t2 = new QThread;
QThread *t3 = new QThread;
camera->moveToThread(t1);
processer->moveToThread(t2);
tracker->moveToThread(t3);
serial->moveToThread(t3);

// Connections
QObject::connect(t1, SIGNAL(started()), camera, SLOT(captureImage()));
QObject::connect(camera, SIGNAL(capturedImage(cv::Mat*)), troller, SLOT(inputImage(cv::Mat*)));
QObject::connect(t2, SIGNAL(started()), troller, SLOT(processerReady()));
QObject::connect(troller, SIGNAL(image(cv::Mat*)), processer, SLOT(processImage(cv::Mat*)));
QObject::connect(troller, SIGNAL(requestImage()), camera, SLOT(captureImage()));
QObject::connect(processer, SIGNAL(posXposY(int,int)), tracker, SLOT(position(int,int)));
QObject::connect(tracker, SIGNAL(directionAndSpeed(int,int)), serial, SLOT(sendData(int,int)));
QObject::connect(processer, SIGNAL(readyForWork()), troller, SLOT(processerReady()));
QObject::connect(processer, SIGNAL(processedImage(cv::Mat*)), troller, SLOT(processedImage(cv::Mat*)));
// Need to add finish/clean up stuff for terminating threads.

// Starting Threads
t1->start();
t2->start();
t3->start();

// wait for key to exit
while (true) {
     c = cvWaitKey(1);
    if(c!=-1)
    {
        // Add thread termination before breaking the loop.
        // If pressed, break out of the loop
        break;
    }
}
return 0;
}

【问题讨论】:

  • 请尽量避免将 指针 传递给 cv::Mat,而是使用引用(破坏内部引用计数的高风险)。此外,您从 VideoCapture 获得的内容指向 驱动程序 内存。如果要将帧传递给另一个线程(甚至在捕获循环之外使用帧),则必须克隆帧
  • 通过完全摆脱指针和引用解决了这个问题。我们尝试按照建议使用引用,但后来我们得到了错误:“QObject::connect: Cannot queue arguments of type 'cv::Mat&' (确保 'cv::Mat&' 使用 qRegisterMetaType( ).)”。我们无法注册 cv::Mat&,但 cv::Mat 工作正常。
  • @user3434960 你应该添加并接受你自己的答案。

标签: c++ qt opencv


【解决方案1】:

通过完全摆脱指针和引用解决了这个问题。我们尝试按照建议使用引用,但最终我们得到了错误:“QObject::connect: 无法对 'cv::Mat&' 类型的参数进行排队(确保使用 qRegisterMetaType() 注册了 'cv::Mat&'。) ”。我们无法注册 cv::Mat&,但 cv::Mat 工作正常。

【讨论】:

    猜你喜欢
    • 2015-10-13
    • 2014-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多