您当前的位置: 首页 >  ide
  • 5浏览

    0关注

    478博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

Qt开发高级进阶: WebCamera(UVC)摄像头使用QAbstractVideoSurface捕获视频帧到QImage

高精度计算机视觉 发布时间:2022-06-15 17:05:34 ,浏览量:5

通常,如果你只是想打开UVC(web camera)并显示数据的话,那最简单的方式就是使用类似下面的代码,

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = nullptr):
        QWidget(parent),
        ui(new Ui::Widget)
    {
        ui->setupUi(this);
        mCamera = new QCamera(this);
        mCameraViewfinder = new QCameraViewfinder(this);
        mCameraImageCapture = new QCameraImageCapture(mCamera, this);
        mLayout = new QVBoxLayout;
        mCamera->setViewfinder(mCameraViewfinder);
        mLayout->addWidget(mCameraViewfinder);
        mLayout->setMargin(0);
        ui->scrollArea->setLayout(mLayout);
    }

    ~Widget(){...};

private slots:
    void on_captureButton_clicked(){...};
    void on_stopButton_clicked(){...};
    void on_playButton_clicked(){...};

private:
    Ui::Widget *ui;
    QCamera *mCamera;
    QCameraViewfinder *mCameraViewfinder;
    QCameraImageCapture *mCameraImageCapture;
    QVBoxLayout *mLayout;
};

如果使用QGraphicsView和QGraphicsScene的方式,则通常用QGraphicsVideoItem会更合适,

和前面的代码类似,

QGraphicsView* gView = NULL;
QGraphicsScene* gScene = NULL;
QGraphicsVideoItem* gVideoItem = NULL;

    mCamera = new QCamera(this);

    gScene = new QGraphicsScene(0, 0, 800, 600);
    gView = new QGraphicsView;
    gView->setScene(gScene);
    ui->gridLayout->addWidget(gView); //setCentralWidget(view);

    gVideoItem = new GraphVideoItem;

    mCamera->setViewfinder(gVideoItem);
    gVideoItem->setSize(QSizeF(800, 600));
    gVideoItem->setPos(0, 0);
    gScene->addItem(gVideoItem);

以上的问题是,如果我们 需要把每一帧数据收集起来,例如压缩成mp4,或者通过网络发送出去,或者需要对他进行视觉图形处理(这在机器视觉中是必须的),那就必须想办法把每一帧图像转变成QImage才行。

这里我就不讲理论了,我把这个写成了一个简单易用的头文件,除了QT之外,没有任何其他依赖。如果想看完整的demo,请参考链接:

https://github.com/SpaceView/WebCamera_to_QImage_for_Qt

如果只想用到这个类,可以直接看下面的源码(源码是参考了附录【1】的源码并进行了一些修改,同时也修复了一些不同版本引发的BUG),如下,

#ifndef WEBCAME_H
#define WEBCAME_H

#include 
#include 
#include 
#include 
#include 
#include 
#include 

#include 

struct CameraInfo
{
    QString      identify;    /* Identify of device (maybe a device path) */
    QString      description; /* For display */
    QList resolutionList;
    QStringList  formatList;
};

enum FormatType {
    MJPEG,
    YUYV
};

struct Format {
    int w;
    int h;
    FormatType imageFormat;
    int frameRate;
};


static QImage imageFromVideoFrame(const QVideoFrame& buffer)
{
    QImage img;
    QVideoFrame frame(buffer);  // make a copy we can call map (non-const) on
    frame.map(QAbstractVideoBuffer::ReadOnly);
    QImage::Format imageFormat = QVideoFrame::imageFormatFromPixelFormat(
                frame.pixelFormat());
    // BUT the frame.pixelFormat() is QVideoFrame::Format_Jpeg, and this is
    // mapped to QImage::Format_Invalid by
    // QVideoFrame::imageFormatFromPixelFormat
    if (imageFormat != QImage::Format_Invalid) {
        img = QImage(frame.bits(),
                     frame.width(),
                     frame.height(),
                     // frame.bytesPerLine(),
                     imageFormat);
    } else {
        // e.g. JPEG
        int nbytes = frame.mappedBytes();
        img = QImage::fromData(frame.bits(), nbytes);
    }
    frame.unmap();
    return img;
}

class WebCameraCapture : public QAbstractVideoSurface
{
    Q_OBJECT
public:
    enum PixelFormat {
        Format_Invalid,
        Format_ARGB32,
        Format_ARGB32_Premultiplied,
        Format_RGB32,
        Format_RGB24,
        Format_RGB565,
        Format_RGB555,
        Format_ARGB8565_Premultiplied,
        Format_BGRA32,
        Format_BGRA32_Premultiplied,
        Format_BGR32,
        Format_BGR24,
        Format_BGR565,
        Format_BGR555,
        Format_BGRA5658_Premultiplied,

        Format_AYUV444,
        Format_AYUV444_Premultiplied,
        Format_YUV444,
        Format_YUV420P,
        Format_YV12,
        Format_UYVY,
        Format_YUYV,
        Format_NV12,
        Format_NV21,
        Format_IMC1,
        Format_IMC2,
        Format_IMC3,
        Format_IMC4,
        Format_Y8,
        Format_Y16,

        Format_Jpeg,

        Format_CameraRaw,
        Format_AdobeDng,

#ifndef Q_QDOC
        NPixelFormats,
#endif
        Format_User = 1000
    };

    Q_ENUM(PixelFormat)

    explicit WebCameraCapture(QObject *parent = 0) : QAbstractVideoSurface(parent)
    {
    }

    QList supportedPixelFormats(QAbstractVideoBuffer::HandleType handleType = QAbstractVideoBuffer::NoHandle) const override
    {
        Q_UNUSED(handleType);
        return QList()
                            
关注
打赏
1659856567
查看更多评论
0.0856s