用Qt显示图像流 [英] Displaying a stream of images with Qt

查看:1009
本文介绍了用Qt显示图像流的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当前解决方案如下:

//paintlabel.h
class PaintLabel : public QWidget
{
    Q_OBJECT

public:
    explicit PaintLabel(QWidget *parent = 0);

public slots:
    void setImage(char *img_ptr, QSize img_size, int pitch);

protected:
    void paintEvent(QPaintEvent *event) override;

private:
    QImage image;

}

//paintlabel.cpp

PaintLabel::PaintLabel(QWidget *parent) : QWidget(parent)
{
    setAttribute(Qt::WA_NoSystemBackground, true);
}

void PaintLabel::setImageLive(char *img_ptr, QSize img_size, int pitch)
{
    image = QImage((uchar *)img_ptr, img_size.width(), img_size.height(), pitch, QImage::Format_RGB32).scaled(this->size());
    update();  
}

void PaintLabel::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event);
    QPainter painter;
    painter.begin(this);
    if (!image.isNull()) {
        const QPoint p = QPoint(0,0);
        painter.drawImage(p, image);
    }
    painter.end();
}

我希望每秒20-40帧.问题是,性能随尺寸的增长确实不好.尺寸约为fullHD时,绘画需要1-2 ms.但是,如果我将其大小调整为4k,它会变得非常滞后(绘画时间为16毫秒).有什么方法可以实现相同的功能,但需要更少的资源消耗?

I expect 20-40 frames per second. The problem is, that the performance scales really bad with size. With the size around fullHD the painting takes 1-2 ms. But if I resize it to 4k, it gets awfully laggy (16 ms painting). Is there any way to implement the same functionality but with less resource consumption?

从理论上讲,如果我将父类更改为QOpenGLWidget,则QPainter会以硬件加速运行.但是这样做,运行起来甚至更慢.

Theoretically, if I change the parent class to QOpenGLWidget, the QPainter runs with hardware acceleration. But doing it, it runs even slower.

推荐答案

首先,代码中的限制因素之一似乎是scaled()函数.尝试将其取出,您应该会看到速度有所提高.

Firstly one of the limiting factors in your code seems to be the scaled() function. Try taking it out and you should see some speed-up.

其他问题仅仅是QImage性能的限制.有关更多信息,请参考此问题. 如何提高QPainter性能?

Other problem is simply the limitation of performance of QImage. Refer this question for more information. How can QPainter performance be improved?

QPainter将使用软件光栅化器绘制QImage实例.

QPainter will use software rasterizer to draw QImage instances.

引用 http://doc.qt.io/qt-5/topic-graphics.html 了解更多信息.

您不能选择QPixmap,因为整个缓冲区也会改变每一帧.

You cant go for QPixmap since your entire buffer changes each frame as well.

您可以尝试使用QOpenGLPaintDevice来使QPainter使用硬件加速.您尝试过的另一种方法是QOpenGLWidget.

You can try using the QOpenGLPaintDevice to make the QPainter use hardware acceleration. Another approach you tried is QOpenGLWidget.

QOpenGLWidget-画家也可以在QOpenGLWidget上打开.提供此功能是为了方便,因为从技术上讲,这与使用QOpenGLPaintDevice没什么不同.

QOpenGLWidget - A painter can also be opened on a QOpenGLWidget. This is provided as a convenience, since technically this is no different than using QOpenGLPaintDevice.

引用上面相同的qt链接.

refer the same qt link above.

所以是的,从技术上讲应该更快,但是由于要调整Widget的大小,从而调整OpenGL Viewport的大小,因此每次都会重新构造下面的缓冲区.因此,增长速度要慢得多.请注意,QOpenGLWidget本身会处理某些功能,例如glViewport().当您尝试优化性能时,这没有用.

So yes this should technically be faster, BUT since you are resizing the Widget thereby resizing the OpenGL Viewport, the underneath buffers get re-made each time. Hence the slowdown is much more. Do note that QOpenGLWidget handles some functions such as glViewport() by itself. This is not useful when you are trying to optimize performance.

以下是一些建议

  1. 我相信主要的问题是QImage的处理.我建议您设置自己的OpenGL场景,只需使用一个四边形来渲染纹理,然后尝试在每帧中写入纹理.缩放将在GPU上处理,因此肯定会更快.

  1. I believe the major issue is the handling of QImage. I suggest you setup your own OpenGL Scene, simply with one quad to render a texture, and try writing to the texture each frame. The scaling will be handled on the GPU so it will surely be faster .

或者,您可以使用glDrawPixels()将图像从主机内存(RAM)渲染到帧缓冲区.虽然这不会为您处理缩放.请参阅 https://www.opengl.org/sdk/docs/man2/xhtml/glDrawPixels.xml 了解更多信息.

Alternatively you can use glDrawPixels() to render the image from host memory (RAM) to the frame buffer. Although this will not handle scaling for you. refer to https://www.opengl.org/sdk/docs/man2/xhtml/glDrawPixels.xml for more information.

我目前正在使用QGLWidget和自定义OpenGL纹理并绘制调用以实现快速更新(> 60 FPS).我观察到这比QImage/Qpixmap方法快8到10倍.请注意,我的纹理尺寸从未超过700x700.此外,我的图像始终存储在GPU内存中,并通过映射的CUDA内核进行更新.

I am currently using QGLWidget and custom OpenGL texture and draw calls to achieve a fast update (>60 FPS). I have observed this to be about 8x to 10x faster than the QImage / Qpixmap method. Please note that my texture size never surpasses 700x700. Also my Image is always stored on GPU memory and updated by mapped CUDA kernel.

您肯定应该看到提速,但是我不能保证它会满足您的FPS要求.

You should definitely see a speed-up but I can't guarantee it will meet your FPS requirement.

这篇关于用Qt显示图像流的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆