首页 > 其他分享 >Qt调用摄像头二,Pro版

Qt调用摄像头二,Pro版

时间:2023-03-31 16:34:38浏览次数:31  
标签:kuangxuan clicked Qt Pro Dialog include void 摄像头

本示例,为纯Qt调用摄像头,功能会比版本一要多一点:打开摄像头,设置参数,完整拍照,框选拍照,切换分辨率,旋转,水平镜像,垂直镜像,放大,缩小

上一个版本,使用的显示窗口直接显示出摄像头画面,所以可操作性有限,

没关系,这个版本使用的另一种方法:打开设备,获取视频帧,自己把视频帧画上去,这样就操作的东西就多了。

 

涉及到的功能有:

  获取摄像头列表

  获取摄像头分辨率

  获取摄像头帧率

  获取摄像头支持的视频模式

  设置摄像头参数

  完整拍照,框选拍照(使用鼠标左键画出框选的区域)

  旋转(代码中只写向统一方向旋转)

  镜像(水平镜像,垂直镜像)

  缩放(放大,缩小)

 

本demo还存在两个小bug
1.旋转后,图像不居中。修复方法:paintEvent 中加入判断,开启旋转后,图像设置居中,空白区域白色填充
2.框选后,无法取消框选。修复方法:mouseReleaseEvent 中加入判断,要是鼠标抬起的坐标和按下的坐标一致,就不框选。或者设置鼠标右键取消框选

 

QT       += core gui multimedia multimediawidgets printsupport

 

 

#ifndef DIALOG_H
#define DIALOG_H

#include <QDialog>
#include <QCamera>                  // 摄像头
#include <QCameraInfo>              // 摄像头信息
#include <QVideoProbe>              // 视频
#include <QVideoWidget>             // 视频显示窗口
#include <QCameraImageCapture>      // 拍照
#include <QDebug>

#include <QPaintEvent>
#include <QPainter>
#include <QMouseEvent>


QT_BEGIN_NAMESPACE
namespace Ui { class Dialog; }
QT_END_NAMESPACE

class Dialog : public QDialog
{
    Q_OBJECT

public:
    Dialog(QWidget *parent = nullptr);
    ~Dialog();

    //CameraDevice *m_pCameraDevice;

    void paintEvent(QPaintEvent *e);
    void mousePressEvent(QMouseEvent* e);
    void mouseReleaseEvent(QMouseEvent* e);


public slots:
    void slotOnProbeFrame(const QVideoFrame &frame);

private slots:
    void on_pushButton_clicked();
    void on_pushButton_2_clicked();
    void on_pushButton_3_clicked();
    void on_pushButton_4_clicked();
    void on_pushButton_5_clicked();
    void on_pushButton_6_clicked();
    void on_pushButton_7_clicked();

private:
    Ui::Dialog *ui;

    // 需要用到的一些参数
    QImage m_img;                  // 视频帧,全局图像
    int m_rotate = 0;              // 旋转角度
    bool m_horizontal = false;     // 水平镜像
    bool m_vertical = false;       // 垂直镜像
    double m_scaled = 1.0;         // 缩放
    bool m_kuangxuan_state = false;// 框选状态
    QRect m_kuangxuan;             // 框选矩形位置

    QCamera *dev = nullptr;        // 摄像头
    QVideoProbe *video = nullptr;  // 视频
    QList<QSize> resolution;       // 分辨率
};
#endif // DIALOG_H

 

 

 

 

#include "dialog.h"
#include "ui_dialog.h"

Dialog::Dialog(QWidget *parent)
    : QDialog(parent)
    , ui(new Ui::Dialog)
{
    ui->setupUi(this);

    // 初始化,读取摄像头信息
    QList<QCameraInfo> cameras = QCameraInfo::availableCameras();
    foreach(const QCameraInfo &cameraInfo, cameras)
    {
        qDebug() << cameraInfo.deviceName();    // 摄像头完整信息
        qDebug() << cameraInfo.description();   // 摄像头名称
    }


    dev = new QCamera(cameras.at(0));           // 创建设备
    video = new QVideoProbe;                    // 创建视频
    if(video != nullptr)
    {
        video->setSource(dev);
        connect(video, SIGNAL(videoFrameProbed(QVideoFrame)), this, SLOT(slotOnProbeFrame(QVideoFrame)), Qt::QueuedConnection);
    }
    dev->setCaptureMode(QCamera::CaptureViewfinder);    // 设置捕捉模式为视频,CaptureViewfinder,CaptureVideo,CaptureStillImage
    dev->load();                                        // 加载摄像头


    // 获取分辨率列表
    QList<QSize> resolution_old = dev->supportedViewfinderResolutions();
    resolution = {};
    while(!resolution_old.isEmpty())
    {
        resolution.append(resolution_old.takeLast());
    }
    qDebug() << resolution.length();
    for (int i=0; i< resolution.length(); i++) {
        qDebug() << resolution.at(i).width() << "_" << resolution.at(i).height();
    }

    // 获取摄像头帧率
    QList<QCamera::FrameRateRange> frameRate = dev->supportedViewfinderFrameRateRanges();
    foreach (auto i, frameRate)
    {
        qDebug() << i.maximumFrameRate;
    }

    // 获取摄像头支持视频格式
    QList<QVideoFrame::PixelFormat> pixelFormat = dev->supportedViewfinderPixelFormats();
    foreach (auto i, pixelFormat)
    {
        qDebug() << i;
    }

    // 设置分辨率 & 帧率 (不能同时设置最大帧率和最小帧率,会报错)
    QCameraViewfinderSettings set;
    set.setResolution(resolution.at(0));
    set.setMinimumFrameRate(15.0);
    set.setPixelFormat(QVideoFrame::Format_Jpeg);
    dev->setViewfinderSettings(set);
    dev->start();
}

Dialog::~Dialog()
{
    delete ui;
}


void Dialog::slotOnProbeFrame(const QVideoFrame &frame)
{
    //qDebug() << "获取到视频帧";

    QVideoFrame cframe(frame);
    cframe.map(QAbstractVideoBuffer::ReadOnly);

    // Windows上可以直接 QImage::fromData,但是Mac上跑不起来,所以需要做下判断
    QImage::Format imageFormat = QVideoFrame::imageFormatFromPixelFormat(cframe.pixelFormat());
    if (imageFormat != QImage::Format_Invalid)
    {
        m_img = QImage(cframe.bits(), cframe.width(), cframe.height(), imageFormat);
    }
    else
    {
        m_img = QImage::fromData(cframe.bits(), cframe.mappedBytes());
    }
    cframe.unmap();

    // 旋转
    QMatrix matrix;
    switch (m_rotate) {
        case 1:{matrix.rotate(90);}break;
        case 2:{matrix.rotate(180);}break;
        case 3:{matrix.rotate(270);}break;
    }
    m_img = m_img.transformed(matrix);

    // 镜像
    m_img = m_img.mirrored(m_horizontal, m_vertical);

    // 缩放,数字记得写真实的分辨率
    m_img = m_img.copy(QRect(3264*(m_scaled-1)/2, 2448*(m_scaled-1)/2, 3264-3264*(m_scaled-1), 2448-2448*(m_scaled-1)));

}

void Dialog::paintEvent(QPaintEvent *e)
{
    QPainter p(this);
    p.setPen(Qt::red);
    p.drawImage(ui->widget->geometry(), m_img);
    if (m_kuangxuan_state){p.drawRect(m_kuangxuan);}
    update();
}

void Dialog::mousePressEvent(QMouseEvent* e)
{
    if (ui->widget->geometry().contains(e->pos()))
    {
        m_kuangxuan.setX(e->pos().x());
        m_kuangxuan.setY(e->pos().y());
        m_kuangxuan_state = false;
    }

}

void Dialog::mouseReleaseEvent(QMouseEvent* e)
{
    if (ui->widget->geometry().contains(e->pos()))
    {
        m_kuangxuan.setWidth(e->pos().x() - m_kuangxuan.x());
        m_kuangxuan.setHeight(e->pos().y() - m_kuangxuan.y());
        m_kuangxuan_state = true;
        qDebug() << "kuangxuan rect:" << m_kuangxuan;
    }
}

void Dialog::on_pushButton_clicked()
{
    // 拍照
    if (m_kuangxuan_state)
    {
        // 框选拍照
        QRect r2 = ui->widget->geometry();
        QRect r3;
        double b = m_img.width() / r2.width();
        double x = (m_kuangxuan.x() - r2.x()) > 0 ? (m_kuangxuan.x() - r2.x()) * b : 0;
        double y = (m_kuangxuan.y() - r2.y()) > 0 ? (m_kuangxuan.y() - r2.y()) * b : 0;
        r3.setX(x);
        r3.setY(y);
        r3.setWidth((m_kuangxuan.width() + (m_kuangxuan.x() - r2.x())) * b);
        r3.setHeight((m_kuangxuan.height() + (m_kuangxuan.y() - r2.y())) * b);
        m_img.copy(r3).save("D:\\5.jpg");

    }
    else
    {
        m_img.save("D:\\4.jpg");
    }
}

void Dialog::on_pushButton_2_clicked()
{
    // 切换分辨率
    qDebug() << resolution.at(1);

    dev->load();
    QCameraViewfinderSettings set;
    set.setResolution(resolution.at(1));
    set.setMinimumFrameRate(15.0);
    set.setPixelFormat(QVideoFrame::Format_Jpeg);
    dev->setViewfinderSettings(set);
    dev->start();
}

void Dialog::on_pushButton_3_clicked()
{
    // 旋转
    if (m_rotate < 3){m_rotate += 1;}else{m_rotate = 0;}
}

void Dialog::on_pushButton_4_clicked()
{
    // 水平镜像
    m_horizontal = m_horizontal == true ? false : true;
}

void Dialog::on_pushButton_5_clicked()
{
    // 垂直镜像
    m_vertical = m_vertical == true ? false : true;
}

void Dialog::on_pushButton_6_clicked()
{
    // 放大
    if (m_scaled < 1.9){m_scaled+=0.1;}else{m_scaled=1.9;}
    qDebug() << "scaled:" << m_scaled;
}

void Dialog::on_pushButton_7_clicked()
{
    // 缩小
    if(m_scaled>1.1){m_scaled-=0.1;}else{m_scaled=1.0;}
    qDebug() << "scaled:" << m_scaled;
}

 

 

 

嘿,成长+1

 

标签:kuangxuan,clicked,Qt,Pro,Dialog,include,void,摄像头
From: https://www.cnblogs.com/shiyixirui/p/17276624.html

相关文章

  • xmind升级成pro
    Xmind8update9破解1、下载并安装xmind-8-update9-windows.exe2、下载破解文件XMindCrack.jar将此文件放到XMind安装路径下3、修改XMind.ini文件打开安装路径下的C:\ProgramFiles(x86)\XMind\XMind.ini文件,最后添加一行-javaagent:C:\ProgramFiles(x8......
  • FIT5222 executing and pipelining processes
     FIT5222Assignment2:executingandpipeliningprocesses 1/4Assignment2:executingandpipeliningprocessesDue30Aprby23:59Points10Availableuntil4Mayat23:59OverviewAssignment2isnowavailable.It'sworth10%ofyouroverallmarkf......
  • Qt音视频开发32-qmedia内核回调拿图片数据
    一、前言使用qmediaplayer来打开视频并播放,默认首选会采用QVideoWidget控件来展示,优点是不用自己来绘制,一切交给了QVideoWidget控件,这样可以做到极低的CPU占用,缺点也明显,就是无法拿到每一帧的图片,很多时候我们还需要主动拿到每一帧的图片来运算做人工智能,通过不断的截图虽然也能......
  • Project 'org.springframework.boot:spring-boot-starter-parent:XXX' not found
    问题:Project'org.springframework.boot:spring-boot-starter-parent:XXX'notfound当spring-boot-starter-parent下面的版本报红时并不是这个版本不存在,而是因为idea会默认缓存Maven本地仓库已存在的中的依赖项。只是我们引入的的父依赖版本在本地仓库中不存在,所以就报......
  • qt窗体的移动
    /// <summary>    /// 获得鼠标按下事件    /// </summary>    /// <param name=""></param>    void  mousePressEvent(QMouseEvent*) override; /// <summary> /// 获得鼠标移动事件 /// </summary> /// <param name=""......
  • 时钟小程序 所用类qwidget QTime Qpalette
    DigiClock::DigiClock(QWidget&nbsp;*parent) :&nbsp;QLCDNumber(parent){ //设置时钟背景 QPalette&nbsp;p&nbsp;=&nbsp;palette();<br/>//设置调色板颜色QPalette::Window设置背景色 p.setColor(QPalette::Window,&nbsp;Qt::blue);<br/>......
  • C语言以结构体的方式写入eeprom数据
    unsignedcharmin_change0=0,//要保存的变量值第一组,每一次改变都会保存unsignedcharmin_change_backup0=0;//该变量为中间变量,用于与min_change做对比,下同unsignedcharmin_change1=0,//要保存的变量值第二组,每一次改变都会保存unsignedcharmin_change_b......
  • 浅谈Zabbix与Prometheus区别
    Zabbix和Prometheus都是非常流行的监控系统。它们有许多相似之处,但也有一些不同之处。以下是Zabbix和Prometheus监控对比的一些关键点:1、数据模型和查询语言Prometheus使用一个称为PromQL的查询语言来查询和处理时间序列数据。PromQL支持许多数据模型和查询功能,包括度量标准、标......
  • c# mqtt高性能服务器端源代码 开源框架包括服务器和客户端,支持mqtt3.0及5.0
    c#mqtt高性能服务器端源代码。你还在使用第三方服务软件吗?不如试试这个开发框架,助你一臂之力,无限制,无全开源,无版权约束,全是自主开发。开源框架包括服务器和客户端,支持mqtt3.0及5.0。可嵌入到自己的服务系统及软件客户端中,不受第三方约束。你要问我稳定性如何?我能回答的是已经......
  • 容器云平台监控告警体系(三)—— 使用Prometheus Operator部署并管理Prometheus Server
    1、概述 PrometheusOperator是一种基于Kubernetes的应用程序,用于管理Prometheus实例和相关的监控组件。它是由CoreOS开发的开源工具,旨在简化Prometheus的部署和配置。容器云平台通过使用PrometheusOperator简化在Kubernetes下部署和管理Prmetheus的复杂度,其通过prome......