[Qt学习笔记]Qt实现多摄像头的识别、显示、截图、分辨率帧率设置等功能

前言 项目中需要使用USB 的免驱摄像头进行采集图像,一般这种USB的摄像头直接可以使用Qt中的QCamera获取图像及相关各种操作,这里基于QCamera来实现摄像头的显示和抓图的基本功能。
一、功能介绍和成果展示

多摄像头的信息获取、显示和抓图功能
  • CameraInfo遍历设备获取多摄像头信息
  • 获取摄像头的分辨率和最大帧率,并进行选择设置
  • 实现单张抓图和连续抓拍功能

    二、实现流程1.配置工作首先要在Pro文件中加入multimedia模块,如下
    [Qt学习笔记]Qt实现多摄像头的识别、显示、截图、分辨率帧率设置等功能
    文章图片

    在ui中把图像视频显示的widget提升为QVideoWidget
    [Qt学习笔记]Qt实现多摄像头的识别、显示、截图、分辨率帧率设置等功能
    文章图片

    2.遍历摄像头设备调用QCameraInfo来获取可用的摄像头设备列表
    cameras = QCameraInfo::availableCameras(); //获取可用摄像头设备列表 int index = cameras.size(); for(int i=0; icmb_CameraName->addItem(cameras.at(i).description()); }

    3.获取摄像头支持的分辨率和最大帧率获取摄像头的参数并填入UI控件中
    void MainWindow::SetFrameResolution() { mResSize.clear(); mResSize = m_camera->supportedViewfinderResolutions(); ui->cmb_Resolution->clear(); int i=0; foreach (QSize msize, mResSize) { qDebug()<cmb_Resolution->addItem(QString::number(msize.width(),10)+"*"+QString::number(msize.height(),10), i++); }//摄像头支持分辨率打印 ui->cmb_Resolution->setCurrentIndex(0); mMaxFrame.clear(); int j; for(j=0; j< m_camera->supportedViewfinderFrameRateRanges().length(); j++) { qreal frameRates = m_camera->supportedViewfinderFrameRateRanges().at(j).maximumFrameRate; mMaxFrame.append(frameRates); ui->cmb_MaxFrameRate->addItem(QString::number(frameRates)); } ui->cmb_MaxFrameRate->setCurrentIndex(j-1); }

    4.显示视频和抓图操作显示视频时可以把捕捉模式设置为静态帧或视频,目前这两种看起来显示效果没差别,如果有大佬知道可以评论告知区别;
    m_camera = new QCamera(this); //初始化摄像头设备 m_camera->setCaptureMode(QCamera::CaptureStillImage); //设置捕捉模式为静态帧 //m_camera->setCaptureMode(QCamera::CaptureVideo); //设置捕捉模式为视频 m_camera->setViewfinder(ui->widgetCamera); //设置 摄像头画面的显示位置 image_capture = new QCameraImageCapture(m_camera); m_camera->start(); //开启摄像头connect(image_capture, SIGNAL(imageCaptured(int, QImage)), this, SLOT(processCapturedImage(int, QImage))); timer_image_capture = new QTimer(this); connect(timer_image_capture,&QTimer::timeout,this,&MainWindow::captureImage); SetFrameResolution();

    三、功能实现代码
    mainwindow.h
    #ifndef MAINWINDOW_H #define MAINWINDOW_H#include #include #include #include #include #include #include namespace Ui { class MainWindow; }class MainWindow : public QMainWindow { Q_OBJECTpublic: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); private slots: //void on_btnCameraCtrl_clicked(); void on_btnSnap_clicked(); void on_btnVedio_clicked(); void processCapturedImage(int request_id, const QImage &img); void captureImage(); void on_cmb_CameraName_activated(int index); void on_cmb_Resolution_activated(int index); void on_cmb_MaxFrameRate_activated(int index); private: Ui::MainWindow *ui; QList cameras; QCamera* m_camera; //摄像头设备 QCameraImageCapture* image_capture; QTimer *timer_image_capture; //图像抓图QList mResSize = {}; //分辨率List QList mMaxFrame = {}; //最大帧率 QTimer *myTimer; //状态栏时间显示 //相机状态标志量参数 QLabel * m_status1; QLabel * m_status2; QLabel * m_status3; void initCamera(); void initForm(); void SetFrameResolution(); void UpdateCameraStatus(); }; #endif // MAINWINDOW_H

    mainwindow.cpp
    #pragma execution_character_set("utf-8") #include "mainwindow.h" #include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); this->initCamera(); this->initForm(); }MainWindow::~MainWindow() { delete ui; }void MainWindow::initCamera() { cameras = QCameraInfo::availableCameras(); //获取可用摄像头设备列表 int index = cameras.size(); for(int i=0; icmb_CameraName->addItem(cameras.at(i).description()); }m_camera = new QCamera(this); //初始化摄像头设备 m_camera->setCaptureMode(QCamera::CaptureStillImage); //设置捕捉模式为静态帧 //m_camera->setCaptureMode(QCamera::CaptureVideo); //设置捕捉模式为视频 m_camera->setViewfinder(ui->widgetCamera); //设置 摄像头画面的显示位置 image_capture = new QCameraImageCapture(m_camera); m_camera->start(); //开启摄像头connect(image_capture, SIGNAL(imageCaptured(int, QImage)), this, SLOT(processCapturedImage(int, QImage))); timer_image_capture = new QTimer(this); connect(timer_image_capture,&QTimer::timeout,this,&MainWindow::captureImage); SetFrameResolution(); }void MainWindow::initForm() { myTimer=new QTimer(this); myTimer->start(1000); QLabel * btn = new QLabel(this); connect(myTimer , &QTimer::timeout, [=](){ QDateTime Date_Time =QDateTime::currentDateTime(); QString Time_system = Date_Time.toString("yyyy-MM-dd hh:mm:ss ddd"); btn->setText(Time_system); }); //statusBar()->setStyleSheet(QString("QStatusBar::item{border: 2px}")); statusBar()->setSizeGripEnabled(false); ui->statusBar->addPermanentWidget(btn); m_status1 = new QLabel(this); m_status1->setGeometry(2,2,18,18); m_status2 = new QLabel(this); m_status3 = new QLabel(this); UpdateCameraStatus(); }void MainWindow::UpdateCameraStatus() { QString curCamName = ui->cmb_CameraName->currentText(); QString curCamFrame = ui->cmb_MaxFrameRate->currentText(); QString curCamRes = ui->cmb_Resolution->currentText(); m_status1->setText("摄像头:"+curCamName); ui->statusBar->addWidget(m_status1); m_status2->setText("帧率:"+curCamFrame); ui->statusBar->addWidget(m_status2); m_status3->setText("分辨率:"+curCamRes); ui->statusBar->addWidget(m_status3); }void MainWindow::on_btnSnap_clicked() { image_capture->capture(); }void MainWindow::on_btnVedio_clicked() { int Intervalue = https://www.it610.com/article/ui->spinBox->value(); timer_image_capture->setInterval(Intervalue); timer_image_capture->start(); }void MainWindow::processCapturedImage(int request_id, const QImage &img) { QImage scaledImage = img.scaled(ui->label->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation); ui->label->setPixmap(QPixmap::fromImage(scaledImage)); }void MainWindow::captureImage() { image_capture->capture(); }void MainWindow::on_cmb_CameraName_activated(int index) { index = ui->cmb_CameraName->currentIndex(); qDebug()<<"Index"<< index <<": "<< ui->cmb_CameraName->currentText(); if(m_camera->isAvailable()) { m_camera->stop(); delete m_camera; }m_camera = new QCamera(cameras[index]); m_camera->setCaptureMode(QCamera::CaptureStillImage); m_camera->setViewfinder(ui->widgetCamera); image_capture = new QCameraImageCapture(m_camera); m_camera->start(); connect(image_capture, SIGNAL(imageCaptured(int, QImage)), this, SLOT(processCapturedImage(int, QImage))); SetFrameResolution(); UpdateCameraStatus(); }void MainWindow::SetFrameResolution() { mResSize.clear(); mResSize = m_camera->supportedViewfinderResolutions(); ui->cmb_Resolution->clear(); int i=0; foreach (QSize msize, mResSize) { qDebug()<cmb_Resolution->addItem(QString::number(msize.width(),10)+"*"+QString::number(msize.height(),10), i++); }//摄像头支持分辨率打印 ui->cmb_Resolution->setCurrentIndex(0); mMaxFrame.clear(); int j; for(j=0; j< m_camera->supportedViewfinderFrameRateRanges().length(); j++) { qreal frameRates = m_camera->supportedViewfinderFrameRateRanges().at(j).maximumFrameRate; mMaxFrame.append(frameRates); ui->cmb_MaxFrameRate->addItem(QString::number(frameRates)); } ui->cmb_MaxFrameRate->setCurrentIndex(j-1); }void MainWindow::on_cmb_Resolution_activated(int index) { index = ui->cmb_Resolution->currentIndex(); qDebug()<<"Index"<< index <<": "<< ui->cmb_Resolution->currentText(); qDebug()<<"mResSize:"<setViewfinderSettings(set); UpdateCameraStatus(); }void MainWindow::on_cmb_MaxFrameRate_activated(int index) { index = ui->cmb_MaxFrameRate->currentIndex(); //设置摄像头最大帧率 QCameraViewfinderSettings set; set.setMaximumFrameRate(mMaxFrame[index]); m_camera->setViewfinderSettings(set); UpdateCameraStatus(); }

    四、源码下载源码下载:多摄像头显示源码
总结 【[Qt学习笔记]Qt实现多摄像头的识别、显示、截图、分辨率帧率设置等功能】这里实现了多个相机的视频显示、参数设置和抓图操作,也可以在初始化中使用QList来初始化所有的摄像头并用控件显示,这样就可以同时显示所有摄像头的视频。但是也有部分功能需要进一步研究优化
  • 1.使用QCameraImageCapture类发送的capture的信号,系统会默认保存抓取的图像保存到电脑默认路径,一般在C盘下图片这个文件夹下,如果连续采图会导致本地缓存爆炸增长
  • 2.在实际项目中,一般要采集到图像进行图像操作后再显示,不是单独去实现视频显示,这里需要使用QAbstractVideoSurface捕获视频帧,进行图像处理后再使用QPainter画到显示控件。

    推荐阅读