2

我对 Qt 有疑问。

这是困扰我的代码的一部分:

    void FullScreenImage::QImageIplImageCvt(IplImage *input)
{
    help=cvCreateImage(cvGetSize(input), input->depth, input->nChannels);
    cvCvtColor(input, help, CV_BGR2RGB);
    QImage tmp((uchar *)help->imageData, help->width, help->height, help->widthStep, QImage::Format_RGB888);
    this->setPixmap(QPixmap::fromImage(tmp).scaled(this->size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
    cvReleaseImage(&help);
}


void FullScreenImage::hideOnScreen() {
    this->hide();
    this->clear();
}

void FullScreenImage::showOnScreen(IplImage *slika, int delay) {
    QImageIplImageCvt(slika);
    this->showFullScreen();
    if(delay>0)
 QTimer::singleShot(delay*1000, this, SLOT(hideOnScreen()));
}

因此,该方法showOnScreen使用私有方法从(OpenCV 使用)QImageIplImageCvt创建,然后用于创建以全屏显示图像。类继承。QImageIplImageQPixmapFullScreenImageQLabel

经过一段时间的延迟,全屏图片应该被隐藏,所以我使用QTimer延迟一段时间后触发事件。事件处理程序是hideOnScreen隐藏标签并应清除内存的方法。

问题如下:

每当我调用QPixmap::fromImage时,它都会为像素图数据分配内存并将数据从QImage内存缓冲区复制到QPixmap内存缓冲区。隐藏标签后,QPixmap数据仍然保持分配状态,更糟糕的是,在新QPixmap::fromImage调用之后,为新图片分配了新的内存块,而旧数据并没有从内存中释放出来。这会导致内存泄漏(使用我的测试图片的每个方法调用大约 10 MB)。我该如何解决这个泄漏?

我什至尝试创建一个私有QPixmap变量,存储由QPixmap::fromImage它创建的像素图,然后尝试在hideOnScreen方法中调用它的析构函数,但它没有帮助。

有没有一种非静态的方式来QPixmap创建QImage?或者更好的是,有没有办法QPixmap直接从创建IplImage*

预先感谢您的回答。

4

4 回答 4

1

没有办法QPixmap直接从IplImage*(也不是从cv::Mat)创建。但是,您的解决方案是避免将所有内容写入一行并使用您自己释放的指针。

例如:

if (this->mypixmap)
    delete this->mypixmap;
this->mypixmap = new QPixmap(QPixmap::fromImage(tmp).scaled(this->size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
this->setPixmap(this->mypixmap);

不要忘记mypixmap(NULL)在构造函数中设置。

于 2010-03-26T09:47:09.750 回答
0

你应该可以直接使用QPixmap::loadFromData创建一个QPixmap。所以类似下面的东西可能会起作用:

QPixmap p;
p.loadFromData((uchar *)help->imageData, help->width * help->height);

在不了解 OpenCV 或的情况下IplImage,我不能保证上面的代码片段是正确的,但希望它能让你走上正确的道路。

于 2009-11-17T17:07:01.493 回答
0

我遇到了类似的问题,但是我的代码不同,所以不值得我放在这里。获取您的代码并与我的方法合并将为您提供:

void FullScreenImage::QImageIplImageCvt(IplImage *input)
{
    help=cvCreateImage(cvGetSize(input), input->depth, input->nChannels);
    cvCvtColor(input, help, CV_BGR2RGB);
    QImage* tmp = new QImage((uchar *)help->imageData, help->width, help->height, help->widthStep, QImage::Format_RGB888);
    this->setPixmap(QPixmap::fromImage(*tmp).scaled(this->size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
    delete tmp;
    cvReleaseImage(&help);
}
于 2011-02-04T14:57:37.693 回答
0

使用重载方法为我解决了这个问题:

QPixmap::fromImage(const QImage && image,..)

您可以使用以下命令调用它:

QPixmap::fromImage(std::move(tmp))
于 2019-01-29T16:26:25.187 回答