QT——QCamera摄像头的切换、分辨率切换、截图显示

  • 前言:基于毕业季的线上实习课程项目而学习使用QT开发环境,实习项目是基于树莓派的人脸佩戴口罩检测系统。摄像头设备的选择使用等功能是必选项,下面简单展示QCamera的一些特性的使用。
准备工作
  • 1、安装QT开发环境,可选mingw或vs系列的编译环境,小编使用的是开源mingw环境。。。
  • 2、新建项目,建立项目完成后在项目文件(.pro)文件的第一行修改为:
QT       += core gui multimedia multimediawidgets
  • 3、ui设计,点击ui文件,在ui文件里添加如下标签:
QT——QCamera摄像头的切换、分辨率切换、截图显示_第1张图片
然后对于按钮与下拉菜单都添加槽值(反馈函数)
获取摄像头信息
  • 在MianWindowcpp文件的构造函数中添加以下代码并运行:
	QList cameras = QCameraInfo::availableCameras();
    foreach(const QCameraInfo &cameraInfo, cameras) {
        qDebug() << "CameraInfo:" << cameraInfo;
    }
QT——QCamera摄像头的切换、分辨率切换、截图显示_第2张图片
  • 运行结果如下:
- 从上可以看出有两个摄像头,摄像头其他信息如上图所示。
显示默认摄像头影像
  • 首先在mainwindow.h文件里添加私有变量:camera和viewfind;
private:
    Ui::MainWindow *ui;
    QCamera *camera;
    QCameraViewfinder *viewfind;
  • 接着在mainwindow.cpp文件里的构造函数里添加camera和viewfind初始化的代码
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    QList cameras = QCameraInfo::availableCameras();
    foreach(const QCameraInfo &cameraInfo, cameras) {
        qDebug() << "CameraInfo:" << cameraInfo;
    }
    //添加内容
    camera = new QCamera(this);
    viewfind = new QCameraViewfinder();
    viewfind->show();
    camera->setViewfinder(viewfind);
    camera->start();
}
  • 运行结果如下:
QT——QCamera摄像头的切换、分辨率切换、截图显示_第3张图片
摄像头设备的选择
  • 设备选择项设置在可选下拉菜单里(QComboBox),双击ui文件,选择摄像头后的可选菜单按钮右键选择转到槽,选择activated(int)槽函数,然后相应的.h和.cpp文件会添加槽函数的内容,然后按照下面的代码修改.h和.cpp文件。
  • mainwindow.h
private:
    Ui::MainWindow *ui;
    QCamera *camera;
    QCameraViewfinder *viewfind;
    QList cameras;
  • mainwindow.cpp
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    QComboBox *cameraType = new QComboBox();
    cameraType = ui->cameraType;
    cameraType->clear();
     cameras = QCameraInfo::availableCameras();
    foreach(const QCameraInfo &cameraInfo, cameras) {
        qDebug() << "CameraInfo:" << cameraInfo;
        cameraType->addItem(cameraInfo.description());
    }
    camera = new QCamera(this);
    viewfind = new QCameraViewfinder();
    viewfind->show();
    camera->setViewfinder(viewfind);
    camera->start();
}

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


void MainWindow::on_cameraType_activated(int index)
{
    index = ui->cameraType->currentIndex();
    qDebug()<<"Index"<< index <<": "<< ui->cameraType->currentText();
    camera->stop();
    camera = new QCamera(cameras[index]);
    camera->setCaptureMode(QCamera::CaptureVideo);
    camera->setViewfinder(viewfind);
    camera->start();
}
  • 运行,如下图所示,在摄像头后的选择菜单按钮即可切换不同的摄像头机位。
QT——QCamera摄像头的切换、分辨率切换、截图显示_第4张图片
QT——QCamera摄像头的切换、分辨率切换、截图显示_第5张图片
截图显示
  • 添加QCameraImageCapture这个属性,即可实现截图,实现逻辑为,当点击截图按钮时,将获取截图到imageview控件上显示。
  • 修改后代码如下:
//mianwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include 
#include 
#include 
#include 

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

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

private slots:
    void on_screenshot_clicked();

    void on_cameraType_activated(int index);

    void on_imageCaptured(int id, const QImage &preview);

private:
    Ui::MainWindow *ui;
    QCamera *camera;
    QCameraViewfinder *viewfind;
    QList<QCameraInfo> cameras;
    QCameraImageCapture *imageCapture;
};
#endif // MAINWINDOW_H

//mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include 
#include 

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

    QComboBox *cameraType = new QComboBox();
    cameraType = ui->cameraType;
    cameraType->clear();
     cameras = QCameraInfo::availableCameras();
    foreach(const QCameraInfo &cameraInfo, cameras) {
        qDebug() << "CameraInfo:" << cameraInfo;
        cameraType->addItem(cameraInfo.description());
    }
    camera = new QCamera(this);
    viewfind = new QCameraViewfinder();
    viewfind->show();
    camera->setViewfinder(viewfind);
    imageCapture = new QCameraImageCapture(camera);
    camera->start();

    connect(imageCapture, SIGNAL(imageCaptured(int, QImage)), this, SLOT(on_imageCaptured(int, QImage)));
}

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


void MainWindow::on_cameraType_activated(int index)
{
    index = ui->cameraType->currentIndex();
    qDebug()<<"Index"<< index <<": "<< ui->cameraType->currentText();
    camera->stop();
    camera = new QCamera(cameras[index]);
    camera->setCaptureMode(QCamera::CaptureVideo);
    camera->setViewfinder(viewfind);
    imageCapture = new QCameraImageCapture(camera);
    camera->start();
    connect(imageCapture, SIGNAL(imageCaptured(int, QImage)), this, SLOT(on_imageCaptured(int, QImage)));
}

void MainWindow::on_imageCaptured(int id, const QImage &preview){
    ui->imageview->setPixmap(QPixmap::fromImage(preview));
}

void MainWindow::on_screenshot_clicked()
{
    qDebug()<<"ScreenShot";

    imageCapture->capture();
}

  • 运行效果图如下:
  • 发现一个问题,截的图只显示部分,不显示完全,这是因为我们没有使用布局管理,点击ui文件,将所有控件的布局整理为下图的方式:
QT——QCamera摄像头的切换、分辨率切换、截图显示_第6张图片
  • 再次运行即可出现全部的画面,如下:
  • 5.23日更新:图像在label中等比例缩放:
void MainWindow::on_imageCaptured(int id, const QImage &preview){
    int with = ui->imageview->width();
    int height = ui->imageview->height();
    QPixmap pixmap = QPixmap::fromImage(preview);
    //QPixmap fitpixmap = pixmap.scaled(with, height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);  // 饱满填充
    QPixmap fitpixmap = pixmap.scaled(with, height, Qt::KeepAspectRatio, Qt::SmoothTransformation);  // 按比例缩放
    ui->imageview->setPixmap(fitpixmap);
}
显示分辨率设定
  • 设定分辨率与设定摄像头设备的基本思路是一样的,如下图所示,我使用usb摄像头的最高分辨率600480截好图,然后调整分辨率为160120,在左边实时画面中可以明显感觉到分辨率降低。
QT——QCamera摄像头的切换、分辨率切换、截图显示_第7张图片
整体代码如下:
  • 项目文件目录:
  • Camera.pro
# Camera.pro
QT       += core gui multimedia multimediawidgets

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

CONFIG += c++11

# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \
    main.cpp \
    mainwindow.cpp

HEADERS += \
    mainwindow.h

FORMS += \
    mainwindow.ui

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

  • mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include 
#include 
#include 
#include 
#include 

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
    void setfblComobox(QCamera *camera);

private slots:
    void on_screenshot_clicked();

    void on_cameraType_activated(int index);

    void on_imageCaptured(int id, const QImage &preview);

    void on_fbl_activated(int index);

private:
    Ui::MainWindow *ui;
    QCamera *camera;
    QCameraViewfinder *viewfind;
    QList<QCameraInfo> cameras;
    QCameraImageCapture *imageCapture;
    QList<QSize> mResSize = {};//分辨率List 定义
    QComboBox *box;
};
#endif // MAINWINDOW_H

  • mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include 
#include 

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

    QComboBox *cameraType = new QComboBox();
    box = ui->fbl;
    cameraType = ui->cameraType;
    cameraType->clear();

    cameras = QCameraInfo::availableCameras();
    foreach(const QCameraInfo &cameraInfo, cameras) {
        qDebug() << "CameraInfo:" << cameraInfo;
        cameraType->addItem(cameraInfo.description());
    }
    camera = new QCamera(this);
    viewfind = new QCameraViewfinder();
    viewfind->show();
    camera->setViewfinder(viewfind);
    imageCapture = new QCameraImageCapture(camera);
    camera->start();

    connect(imageCapture, SIGNAL(imageCaptured(int, QImage)), this, SLOT(on_imageCaptured(int, QImage)));

    setfblComobox(camera);
}

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


void MainWindow::on_cameraType_activated(int index)
{
    index = ui->cameraType->currentIndex();
    qDebug()<<"Index"<< index <<": "<< ui->cameraType->currentText();
    camera->stop();
    camera = new QCamera(cameras[index]);
    camera->setCaptureMode(QCamera::CaptureVideo);
    camera->setViewfinder(viewfind);
    imageCapture = new QCameraImageCapture(camera);
    camera->start();
    connect(imageCapture, SIGNAL(imageCaptured(int, QImage)), this, SLOT(on_imageCaptured(int, QImage)));
    setfblComobox(camera);
}

void MainWindow::on_imageCaptured(int id, const QImage &preview){
    ui->imageview->setPixmap(QPixmap::fromImage(preview));
}

void MainWindow::on_screenshot_clicked()
{
    qDebug()<<"ScreenShot";

    imageCapture->capture();
}

void MainWindow::on_fbl_activated(int index){
    index = ui->fbl->currentIndex();
    qDebug()<<"Index"<< index <<": "<< ui->fbl->currentText();
    qDebug()<<"mResSize:"<<mResSize[index];
    //设置摄像头参数
    QCameraViewfinderSettings set;
    set.setResolution(mResSize[index]);
    camera->setViewfinderSettings(set);
}

void MainWindow::setfblComobox(QCamera *camera){

    mResSize.clear();
    mResSize = camera->supportedViewfinderResolutions();
    box->clear();
    int i=0;
    foreach (QSize msize, mResSize) {
       qDebug()<<msize;
       box->addItem(QString::number(msize.width(),10)+"*"+QString::number(msize.height(),10), i++);
    }  //摄像头支持分辨率打印
    box->setCurrentIndex(i-1);
}

  • main.cpp
#include "mainwindow.h"

#include 

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
}

  • mainwindow.ui

<ui version="4.0">
 <class>MainWindowclass>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0x>
    <y>0y>
    <width>800width>
    <height>600height>
   rect>
  property>
  <property name="windowTitle">
   <string>MainWindowstring>
  property>
  <widget class="QWidget" name="centralwidget">
   <property name="font">
    <font>
     <pointsize>7pointsize>
    font>
   property>
   <layout class="QHBoxLayout" stretch="3,2">
    <property name="sizeConstraint">
     <enum>QLayout::SetDefaultConstraintenum>
    property>
    <item>
     <widget class="QWidget" name="widget" native="true">
      <layout class="QVBoxLayout" name="verticalLayout">
       <item>
        <widget class="QLabel" name="imageview">
         <property name="text">
          <string/>
         property>
        widget>
       item>
      layout>
     widget>
    item>
    <item>
     <widget class="QWidget" name="widget_2" native="true">
      <widget class="QComboBox" name="fbl">
       <property name="geometry">
        <rect>
         <x>90x>
         <y>230y>
         <width>191width>
         <height>31height>
        rect>
       property>
       <property name="font">
        <font>
         <pointsize>10pointsize>
        font>
       property>
      widget>
      <widget class="QLabel" name="label_2">
       <property name="geometry">
        <rect>
         <x>10x>
         <y>170y>
         <width>61width>
         <height>21height>
        rect>
       property>
       <property name="font">
        <font>
         <pointsize>12pointsize>
        font>
       property>
       <property name="text">
        <string>摄像头string>
       property>
      widget>
      <widget class="QComboBox" name="cameraType">
       <property name="geometry">
        <rect>
         <x>90x>
         <y>170y>
         <width>191width>
         <height>31height>
        rect>
       property>
       <property name="font">
        <font>
         <pointsize>10pointsize>
        font>
       property>
      widget>
      <widget class="QPushButton" name="screenshot">
       <property name="geometry">
        <rect>
         <x>30x>
         <y>380y>
         <width>221width>
         <height>31height>
        rect>
       property>
       <property name="text">
        <string>截图string>
       property>
      widget>
      <widget class="QLabel" name="label_3">
       <property name="geometry">
        <rect>
         <x>10x>
         <y>230y>
         <width>61width>
         <height>31height>
        rect>
       property>
       <property name="font">
        <font>
         <pointsize>12pointsize>
        font>
       property>
       <property name="text">
        <string>分辨率string>
       property>
      widget>
     widget>
    item>
   layout>
  widget>
 widget>
 <resources/>
 <connections/>
ui>

QT——QCamera摄像头的切换、分辨率切换、截图显示_第8张图片
  • 以上代码个人通过多方渠道搜集学习得来,不免有些问题,如有问题请留言交流~

你可能感兴趣的:(课程实验)