使用 Qt 显示图像流

2024-03-07

当前的解决方案如下所示:

//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 帧。问题是,性能随大小的变化非常糟糕。当尺寸约为全高清时,绘制需要 1-2 毫秒。但如果我将其大小调整为 4k,它会变得非常滞后(绘制 16 毫秒)。有没有什么方法可以实现相同的功能但消耗更少的资源?

理论上,如果我将父类更改为 QOpenGLWidget,QPainter 将使用硬件加速运行。但这样做,它运行得更慢。


首先,代码中的限制因素之一似乎是scaled()功能。尝试将其取出,您应该会看到一些加速。

另一个问题就是 QImage 的性能限制。请参阅此问题以获取更多信息。如何提高 QPainter 的性能? https://stackoverflow.com/questions/6512155

QPainter 将使用软件光栅器来绘制 QImage 实例。

refer http://doc.qt.io/qt-5/topics-graphics.html http://doc.qt.io/qt-5/topics-graphics.html了解更多信息。

你不能去QPixmap因为你的整个缓冲区也会改变每一帧。

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

QOpenGLWidget - 画家也可以在 QOpenGLWidget 上打开。这样做是为了方便,因为从技术上讲,这与使用 QOpenGLPaintDevice 没有什么不同。

请参阅上面相同的 qt 链接。

所以是的,这在技术上应该更快,但是因为您正在调整大小Widget从而调整大小OpenGL Viewport,每次都会重新制作下面的缓冲区。因此,放缓幅度更大。请注意,QOpenGLWidget 处理一些功能,例如glViewport()通过它自己。当您尝试优化性能时,这没有用。

这里有一些建议

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

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

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

您肯定会看到加速,但我不能保证它能满足您的 FPS 要求。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 Qt 显示图像流 的相关文章

随机推荐