c++ - QT,C++ : fast way to draw live image stream from camera on QGraphicsview

标签 c++ qt opencv

我正在编写一个 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/

相关文章:

opencv - 使用 OpenCV fitEllipse() 进行圆拟合

opencv - 使用 OpenCV 的 ffmpeg 后端时如何更改 libx264 配置文件

c++ - 使用模板减少 const 和非 const 非成员函数的代码重复

c++ - 使用值对 std::map 进行排序

c++将参数发送到union(变量 union )

c++ - 如何在 C++ 中读取/加载图像?

mysql - Qt isOpen 方法 false 值 MySQL

opencv - 如何分割图像,使结果只是分割的图像(没有任何背景)

c++ - 从字节到十六进制的令人困惑的基数转换

c++ - 如何从计算线程到GUI线程获取结果-我需要QSharedMemory吗?