QR扫码综合示例教程(五)Qt5.15.2(widget)取出视频帧 取景器帧

本文介绍如何使用Qt处理摄像头帧并解决图像倒置或镜像问题。通过创建自定义的VideoSurface类来捕获和处理摄像头帧,实现实时显示在UI上。

前言

上一篇,使用Qt取出了摄像头的原始帧,得到的图像可能会因摄像头的不同而发生倒置或镜像,本篇教程,我们取出预览的帧,并显示在UI上

在Qt5.15.2取出视频帧 原始帧 示例的基础上修改

一、增加取帧的处理类

删除类Tool_VideoFrames,新建一个类VideoSurface,公有继承自QAbstractVideoSurface

头文件修改如下

#ifndef VIDEOSURFACE_H
#define VIDEOSURFACE_H

#include <QObject>
#include <QAbstractVideoSurface>

class VideoSurface : 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 VideoSurface(QObject *parent = nullptr);

    QList<QVideoFrame::PixelFormat> supportedPixelFormats(
                QAbstractVideoBuffer::HandleType handleType = QAbstractVideoBuffer::NoHandle) const;

        bool present(const QVideoFrame &frame) override;

signals:
        void newVideoFrame(const QImage videoFrame);

};

源文件实现如下类

QList<QVideoFrame::PixelFormat> VideoSurface::supportedPixelFormats(QAbstractVideoBuffer::HandleType handleType) const
{
    Q_UNUSED(handleType);
        return QList<QVideoFrame::PixelFormat>()
                << QVideoFrame::Format_ARGB32
                << QVideoFrame::Format_ARGB32_Premultiplied
                << QVideoFrame::Format_RGB32
                << QVideoFrame::Format_RGB24
                << QVideoFrame::Format_RGB565
                << QVideoFrame::Format_RGB555
                << QVideoFrame::Format_ARGB8565_Premultiplied
                << QVideoFrame::Format_BGRA32
                << QVideoFrame::Format_BGRA32_Premultiplied
                << QVideoFrame::Format_BGR32
                << QVideoFrame::Format_BGR24
                << QVideoFrame::Format_BGR565
                << QVideoFrame::Format_BGR555
                << QVideoFrame::Format_BGRA5658_Premultiplied
                << QVideoFrame::Format_AYUV444
                << QVideoFrame::Format_AYUV444_Premultiplied
                << QVideoFrame::Format_YUV444
                << QVideoFrame::Format_YUV420P
                << QVideoFrame::Format_YV12
                << QVideoFrame::Format_UYVY
                << QVideoFrame::Format_YUYV
                << QVideoFrame::Format_NV12
                << QVideoFrame::Format_NV21
                << QVideoFrame::Format_IMC1
                << QVideoFrame::Format_IMC2
                << QVideoFrame::Format_IMC3
                << QVideoFrame::Format_IMC4
                << QVideoFrame::Format_Y8
                << QVideoFrame::Format_Y16
                << QVideoFrame::Format_Jpeg
                << QVideoFrame::Format_CameraRaw
                << QVideoFrame::Format_AdobeDng;
}

//取出视频帧
bool VideoSurface::present(const QVideoFrame &frame)
{
    if (frame.isValid()) {
        QVideoFrame::imageFormatFromPixelFormat(cloneFrame.pixelFormat()));
        emit newVideoFrame(frame.image());

        return true;
    }
    return false;
}

二、主函数中初始化,并调用

关键代码如下

    //初始化摄像头
    m_camera = new QCamera(QCameraInfo::defaultCamera());
    connect(m_camera, &QCamera::errorOccurred, [this](){
        qDebug()<< "camera error occurred"<<this->m_camera->errorString();
    });

    //初始化取摄像头帧的类
    //m_camera->setViewfinder(ui->videoWidget);

    m_videoSurface = new VideoSurface;
    m_camera->setViewfinder(m_videoSurface);
    connect(m_videoSurface, &VideoSurface::newVideoFrame,
            [this](const QImage videoFrame){
        ui->label->setPixmap(QPixmap::fromImage(videoFrame.scaled(ui->label->size(),Qt::KeepAspectRatio)));
    });
VideoSurface类的newVideoFrame()信号可以直接取出取景器中的帧

运行效果如下

 本教程示例源码

后记

直接取出的帧,解决了图像倒置或镜像的问题,但这不是绝对的,不少移动设备默认前置摄像头的预览是镜像的,请读者注意测试下

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

꧁白杨树下꧂

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值