用Qt显示图像流

And*_*ács 2 c++ opengl 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();
}
Run Code Online (Sandbox Code Playgroud)

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

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

Har*_*ish 5

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

另一个问题仅仅是QImage性能的限制。有关更多信息,请参考此问题。QPainter性能如何改善?

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

有关更多信息,请参见http://doc.qt.io/qt-5/topics-graphics.html

您不能这样做,QPixmap因为整个缓冲区也会更改每个帧。

您可以尝试使用QOpenGLPaintDeviceQPainter使用硬件加速。您尝试过的另一种方法是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

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

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