【发布时间】:2016-08-18 23:26:09
【问题描述】:
我正在编写一个 QT GUI 应用程序,其中连接的摄像头的实时流显示在 QGraphicsview 上。因此,首先将 openCV 图像转换为 QImage,然后再转换为 QPixmap。这被添加到 QGraphicsView 的 QGraphicsScene 中。
带宽不是问题,相机通过以太网或 USB 连接。
我正在使用 Visual Studio 2012 中的 Analyze Toole 版本测试性能,它显示到 QPixmap 的转换非常慢并且需要 60% 的计算时间(显示图像),所以我最终得到1 FPS 左右。到 1920 年,图像为 2560 甚至更大。在将 cv::Ptr stream_image 转换为 QImage 之前缩放它可以显着提高性能,但我需要图像中的所有图像细节。
编辑 这是我如何进行转换的一些代码:
cv::Ptr<IplImage> color_image;
// stream_image is a cv::Ptr<IplImage> and holds the current image from the camera
if (stream_image->nChannels != 3) {
color_image = cvCreateImage(cvGetSize(stream_image), IPL_DEPTH_8U, 3);
cv::Mat gr(stream_image);
cv::Mat col(color_image);
cv::cvtColor(gr, col, CV_GRAY2BGR);
}
else {
color_image = stream_image;
}
QImage *tmp = new QImage(color_image->width, color_image->height, QImage::Format_RGB888);
memcpy(tmp->bits(), color_image->imageData, color_image->width * color_image->height * 3);
// update Scene
m_pixmap = QPixmap::fromImage(*tmp); // this line takes the most time!!!
m_scene->clear();
QGraphicsPixmapItem *item = m_scene->addPixmap(m_pixmap);
m_scene->setSceneRect(0,0, m_pixmap.width(), m_pixmap.height());
delete tmp;
m_ui->graphicsView->fitInView(m_scene.sceneRect(),Qt::KeepAspectRatio);
m_ui->graphicsView->update();
编辑 2 我从 Thomas 的答案中测试了该方法,但它和我的方法一样慢。
QPixmap m_pixmap = QPixmap::fromImage(QImage(reinterpret_cast<uchar const*>(color_image->imageData),
color_image->width,
color_image->height,
QImage::Format_RGB888));
编辑 3 我尝试采纳 Thomas 的第二个建议:
color_image = cvCreateImage(cvGetSize(resized_image), IPL_DEPTH_32F, 3);
//[...]
QPixmap m_pixmap = QPixmap::fromImage(QImage(
reinterpret_cast<uchar const*>( color_image->imageData),
color_image->width,
color_image->height,
QImage::Format_RGB32));
但是在调用 Widget 的 drawEvent 时会崩溃。
问:有没有一种方法可以在 QGraphicsView 中显示图像流,而无需先将其转换为 QPixmap 或任何其他快速/高性能的方式? QGraphicsView 很重要,因为我想为图像添加叠加层。
【问题讨论】:
-
发布一些关于如何进行转换的代码。
-
您不能使用
IPL_DEPTH_32F。你应该使用类似cvCreateImage(cvGetSize(stream_image), IPL_DEPTH_8U, 4)的东西。对于 32 位,我的意思是每种颜色 3x8 位 + Alpha 通道。