前言:基于毕业季的线上实习课程项目而学习使用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::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控件上显示。 修改后代码如下:
#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
#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文件,将所有控件的布局整理为下图的方式:
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: : KeepAspectRatio, Qt: : SmoothTransformation) ;
ui-> imageview-> setPixmap ( fitpixmap) ;
}
显示分辨率设定
设定分辨率与设定摄像头设备的基本思路是一样的,如下图所示,我使用usb摄像头的最高分辨率600480截好图,然后调整分辨率为160 120,在左边实时画面中可以明显感觉到分辨率降低。
整体代码如下:
# 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
#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 = { } ;
QComboBox * box;
} ;
#endif
#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 ) ;
}
#include "mainwindow.h"
#include <QApplication>
int main ( int argc, char * argv[ ] )
{
QApplication a ( argc, argv) ;
MainWindow w;
w. show ( ) ;
return a. exec ( ) ;
}
<?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>
以上代码个人通过多方渠道搜集学习得来,不免有些问题,如有问题请留言交流~