【问题标题】:Qt crashes when picture from OpenCV is too large [duplicate]当来自 OpenCV 的图片太大时,Qt 崩溃 [重复]
【发布时间】:2016-08-26 09:02:40
【问题描述】:

我一直在尝试使用 OpenCV 来捕获摄像头供稿,并在 Qt 中将其显示为 QLabel。按照我找到的指南,这在一定程度上有效。但是,如果我在制作QImage 并设置像素图之前尝试调整 Mat 的大小,应用程序就会彻底崩溃。崩溃的类型是“CameraSoftware.exe 已停止工作”,因此除了找出崩溃的位置之外很难进行调试。

环境是带有 QtCreator 3.6.0 (Qt 5.5.1) 和 OpenCV 3.10 的 64 位窗口。

以下是重要的代码:

void VideoStreamOpenCVWorker::receiveGrabFrame()
{
    if(!toggleStream) return;

    (*cap) >> frameOriginal;
    if(frameOriginal.empty()) return;

    process();

    qDebug() << frameProcessed.cols << "x" << frameProcessed.rows;

    QImage output((const unsigned char *) frameProcessed.data, frameProcessed.cols, frameProcessed.rows, QImage::Format_RGBA8888);

    emit sendFrame(output);
}


void VideoStreamOpenCVWorker::process()
{
    cv::cvtColor(frameOriginal, frameProcessed, cv::COLOR_BGR2RGBA);
    cv::Size size(641,481);
    cv::resize(frameProcessed, frameProcessed, size);
}

这被发送回 QLabel 小部件:

void VideoStreamWidget::receiveFrame(QImage frame){
    this->setPixmap(QPixmap::fromImage(frame));
}

这是它具体崩溃的地方,在“setpixmap”行。

Qlabel 被简单地添加到 QMainWindow 中:

QVBoxLayout *pictureLayout = new QVBoxLayout;
VideoStreamWidget *video = new VideoStreamWidget();
pictureLayout->addWidget(video);

无论出于何种原因,原始帽子图片都是 640x480,我使用的相机是全高清相机。知道是什么原因造成的吗? Qt窗口大小似乎无关紧要,如果我愿意,我可以直接添加一张大图。我只是无法在不崩溃的情况下调整任何内容。

如果我没有提供足够的信息,请尽管问。

编辑:我更新了我的调试器,并在执行 setPixmap 行时收到此错误消息:

The inferior stopped because it triggered an exception.
Stopped in thread 0 by: Exception at 0x7ffe38fdadbb, code: 0xc0000005:
read access violation at: 0x0, flags=0x0 (first chance).

【问题讨论】:

  • 为什么很难调试?在调试器下运行您的应用程序。
  • 我知道它在哪里崩溃,但我只是不知道如何、为什么或如何处理它。很难调试的原因是因为我没有收到可以读出的错误消息。该应用程序只是硬锁定,其中一个窗口“thisapplication.exe 已停止工作”而不是您应该拥有的通常错误消息。
  • @Excludos 确保 frameProcessed 有足够的内存来存储图像。
  • @Excludos 尝试使用 operator new 创建 QImage(在堆上分配)并将指针发送到 slot。
  • 或尝试显式复制:emit sendFrame(output.copy());

标签: c++ qt opencv


【解决方案1】:

感谢 Mailerdaimon 提供答案。将输出作为副本发出

emit sendFrame(output.copy());

成功了。我仍然不确定为什么首先会发生这种情况以及为什么这可以解决问题。

【讨论】:

  • 这是因为 QImage 包装了一个框架,其生命周期和内容不受 QImage 的生命周期约束。当QImage 仍然引用数据时,源框架可能会重新分配或被销毁。
  • 这听起来像是一个不错的解释,如果不是因为如果你不调整它的大小它就可以工作。
  • 谢谢它解决了问题!!!
猜你喜欢
  • 1970-01-01
  • 2012-11-07
  • 1970-01-01
  • 1970-01-01
  • 2011-03-13
  • 2017-08-23
  • 2016-08-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多