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

  • 前言:基于毕业季的线上实习课程项目而学习使用QT开发环境,实习项目是基于树莓派的人脸佩戴口罩检测系统。摄像头设备的选择使用等功能是必选项,下面简单展示QCamera的一些特性的使用。
准备工作
  • 1、安装QT开发环境,可选mingw或vs系列的编译环境,小编使用的是开源mingw环境。。。
  • 2、新建项目,建立项目完成后在项目文件(.pro)文件的第一行修改为:
QT       += core gui multimedia multimediawidgets
  • 3、ui设计,点击ui文件,在ui文件里添加如下标签:
然后对于按钮与下拉菜单都添加槽值(反馈函数)
获取摄像头信息
  • 在MianWindowcpp文件的构造函数中添加以下代码并运行:
	QList<QCameraInfo> cameras = QCameraInfo::availableCameras();
    foreach(const QCameraInfo &cameraInfo, cameras) {
        qDebug() << "CameraInfo:" << cameraInfo;
    }
  • 运行结果如下:
- 从上可以看出有两个摄像头,摄像头其他信息如上图所示。
显示默认摄像头影像
  • 首先在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<QCameraInfo> 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();
}
  • 运行结果如下:
摄像头设备的选择
  • 设备选择项设置在可选下拉菜单里(QComboBox),双击ui文件,选择摄像头后的可选菜单按钮右键选择转到槽,选择activated(int)槽函数,然后相应的.h和.cpp文件会添加槽函数的内容,然后按照下面的代码修改.h和.cpp文件。
  • mainwindow.h
private:
    Ui::MainWindow *ui;
    QCamera *camera;
    QCameraViewfinder *viewfind;
    QList<QCameraInfo> 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();
}
  • 运行,如下图所示,在摄像头后的选择菜单按钮即可切换不同的摄像头机位。
截图显示
  • 添加QCameraImageCapture这个属性,即可实现截图,实现逻辑为,当点击截图按钮时,将获取截图到imageview控件上显示。
  • 修改后代码如下:
//mianwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QCamera>
#include <QCameraViewfinder>
#include <QCameraImageCapture>

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 <QDebug>
#include <QCameraInfo>

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文件,将所有控件的布局整理为下图的方式:
  • 再次运行即可出现全部的画面,如下:
  • 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,在左边实时画面中可以明显感觉到分辨率降低。
整体代码如下:
  • 项目文件目录:
  • 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 <QMainWindow>
#include <QCamera>
#include <QCameraViewfinder>
#include <QCameraImageCapture>
#include <QComboBox>

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 <QDebug>
#include <QCameraInfo>

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 <QApplication>

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

  • mainwindow.ui
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>800</width>
    <height>600</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <widget class="QWidget" name="centralwidget">
   <property name="font">
    <font>
     <pointsize>7</pointsize>
    </font>
   </property>
   <layout class="QHBoxLayout" stretch="3,2">
    <property name="sizeConstraint">
     <enum>QLayout::SetDefaultConstraint</enum>
    </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>90</x>
         <y>230</y>
         <width>191</width>
         <height>31</height>
        </rect>
       </property>
       <property name="font">
        <font>
         <pointsize>10</pointsize>
        </font>
       </property>
      </widget>
      <widget class="QLabel" name="label_2">
       <property name="geometry">
        <rect>
         <x>10</x>
         <y>170</y>
         <width>61</width>
         <height>21</height>
        </rect>
       </property>
       <property name="font">
        <font>
         <pointsize>12</pointsize>
        </font>
       </property>
       <property name="text">
        <string>摄像头</string>
       </property>
      </widget>
      <widget class="QComboBox" name="cameraType">
       <property name="geometry">
        <rect>
         <x>90</x>
         <y>170</y>
         <width>191</width>
         <height>31</height>
        </rect>
       </property>
       <property name="font">
        <font>
         <pointsize>10</pointsize>
        </font>
       </property>
      </widget>
      <widget class="QPushButton" name="screenshot">
       <property name="geometry">
        <rect>
         <x>30</x>
         <y>380</y>
         <width>221</width>
         <height>31</height>
        </rect>
       </property>
       <property name="text">
        <string>截图</string>
       </property>
      </widget>
      <widget class="QLabel" name="label_3">
       <property name="geometry">
        <rect>
         <x>10</x>
         <y>230</y>
         <width>61</width>
         <height>31</height>
        </rect>
       </property>
       <property name="font">
        <font>
         <pointsize>12</pointsize>
        </font>
       </property>
       <property name="text">
        <string>分辨率</string>
       </property>
      </widget>
     </widget>
    </item>
   </layout>
  </widget>
 </widget>
 <resources/>
 <connections/>
</ui>

  • 以上代码个人通过多方渠道搜集学习得来,不免有些问题,如有问题请留言交流~
  • 15
    点赞
  • 65
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
Qt是一种流行的跨平台应用程序开发框架,它提供了丰富的库和工具,使开发者能够轻松构建各种应用程序。要实现Qt远程连接摄像头显示其内容,我们可以采用以下步骤: 1. 首先,确保设备上已经安装了Qt开发环境以及相关的摄像头驱动程序。 2. 创建一个新的Qt项目,并使用适当的库或插件来读取摄像头的视频流。在Qt中,我们可以使用QCamera类来实现这个功能。通过调用QCameraInfo::availableCameras()方法可以获取到可用的摄像头列表。 3. 选择要使用的摄像头,可以通过设置QCamera对象的setCaptureDevice()方法来实现。可以使用QCamera::captureMode()方法来检查是否支持远程连接。 4. 创建一个QCameraViewfinder对象来显示摄像头的视频流。可以使用QWidget或者QQuickView作为视图对象,视需求而定。 5. 设置QCamera对象的视图finder属性为QCameraViewfinder对象,通过调用setViewfinder()方法实现。这将使摄像头的视频流显示在选择的视图对象上。 6. 连接摄像头的信号(如stateChanged())到槽函数中,以便在状态发生变化时进行相应的操作。 7. 在相应的槽函数中,我们可以根据连接的状态来处理不同的逻辑,比如远程连接成功时,可以调用QCamera的start()方法开始播放视频流。 8. 最后,我们可以在Qt应用程序的界面上添加一些控件来控制摄像头的远程连接操作,比如开始、停止、暂停等。 通过以上步骤,我们可以实现Qt远程连接摄像头显示其内容的功能。这将使我们能够方便地获取和处理摄像头的视频流,并在应用程序中以适当的方式进行显示和操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值