我正在编写一个 QT GUI 应用程序,其中连接的相机的实时流显示在 QGraphicsview 上。因此,首先将 openCV 图像转换为 QImage,然后再转换为 QPixmap。这被添加到 QGraphicsView 的 QGraphicsScene。
带宽不是问题,相机通过以太网或 USB 连接。
我正在使用 Visual Studio 2012 中的 Analyze Toole build 测试性能,它表明转换到 QPixmap 的速度非常慢,并且占用了 60% 的计算时间(显示图像),因此我最终得到1 FPS 左右。这些图像是 2560 x 1920 甚至更大。在将 cv::Ptr stream_image 转换为 QImage 之前缩放 cv::Ptr stream_image 可显着提高性能,但我需要图像中的所有图像细节。
编辑 这是我如何进行转换的一些代码:
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 answer 中的方法,但它和我的方法一样慢。
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 很重要,因为我想向图像添加叠加层。
最佳答案
我找到了一个适合我的解决方案,但也用不同的方法进行了一些测试以及它们的性能:
方法一即使在 Debug模式下也是高性能的,并且只占用绘图过程执行时间的 23.7%(在 VS2012 中使用 ANALYZE):
color_image = cvCreateImage(cvGetSize(stream_image), IPL_DEPTH_8U, 4);
cv::Mat gr(stream_image);
cv::Mat col(color_image);
cv::cvtColor(gr, col, CV_GRAY2RGBA,4);
QPixmap m_pixmap = QPixmap::fromImage(QImage(reinterpret_cast<uchar const*>( color_image->imageData),
color_image->width,
color_image->height,
QImage::Format_ARGB32));
方法二 在 Debug模式下仍然有效,占用了 42.1% 的执行时间。当在 QPixmap::fromeImage 中使用以下枚举时
QImage::Format_RGBA8888
方法三 是我在问题中展示的方法,它在调试构建时非常慢,负责 68.3% 的绘图工作量。
但是,当我编译发布版时,所有这三种方法都无缝地同样高效。
关于c++ - QT,C++ : fast way to draw live image stream from camera on QGraphicsview,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36842816/