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

41 篇文章 1 订阅

qt6获取摄像头+抓拍功能  https://blog.csdn.net/qq_63986699/article/details/130440700

Qt6如何实现调用摄像头并显示画面  https://www.yisu.com/zixun/770456.html

=========================================

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

前言

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


一、功能介绍和成果展示

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

    多相机采图和参数设置.gif

    二、实现流程

    1.配置工作

    首先要在Pro文件中加入multimedia模块,如下
     

    1.PNG


    在ui中把图像视频显示的widget提升为QVideoWidget

    提升控件

    2.遍历摄像头设备

    调用QCameraInfo来获取可用的摄像头设备列表

      cameras = QCameraInfo::availableCameras();//获取可用摄像头设备列表
      int index = cameras.size();
      for(int i=0;i<index;i++)
      {
          qDebug()<<index<<cameras.at(i).description();//摄像头的设备名称
          ui->cmb_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()<<msize;
          ui->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 <QMainWindow>
#include <QCamera>
#include <QCameraImageCapture>
#include <QTimer>
#include <QCameraInfo>
#include <QLabel>
#include <QDateTime>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
  Q_OBJECT
  
public:
  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<QCameraInfo> cameras;
  QCamera* m_camera;//摄像头设备
  QCameraImageCapture* image_capture;
  QTimer *timer_image_capture;//图像抓图
  
  QList<QSize> mResSize = {};//分辨率List
  QList<qreal> 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;i<index;i++)
  {
      qDebug()<<index<<cameras.at(i).description();//摄像头的设备名称
      ui->cmb_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 = 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()<<msize;
      ui->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:"<<mResSize[index];
  //设置摄像头分辨率
  QCameraViewfinderSettings set;
  set.setResolution(mResSize[index]);
  m_camera->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();
}

四、源码下载

源码下载:多摄像头显示源码

  https://download.csdn.net/download/fengyaowuhui/85024786


总结

这里实现了多个相机的视频显示、参数设置和抓图操作,也可以在初始化中使用QList来初始化所有的摄像头并用控件显示,这样就可以同时显示所有摄像头的视频。但是也有部分功能需要进一步研究优化

  • 1.使用QCameraImageCapture类发送的capture的信号,系统会默认保存抓取的图像保存到电脑默认路径,一般在C盘下图片这个文件夹下,如果连续采图会导致本地缓存爆炸增长
  • 2.在实际项目中,一般要采集到图像进行图像操作后再显示,不是单独去实现视频显示,这里需要使用QAbstractVideoSurface捕获视频帧,进行图像处理后再使用QPainter画到显示控件。

:https://segmentfault.com/a/1190000041596533

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
qt是一种跨平台的开发框架,ffmpeg是一套音视频编解码的库,rtsp是一种用于传输音视频流的协议。所以如果想要实现摄像头实时显示功能,可以通过qt结合ffmpeg来实现。 首先,我们需要使用ffmpeg来获取每个摄像头的rtsp流并解码。可以使用ffmpeg提供的函数来打开rtsp流并将其解码成原始的音视频数据。通过设置ffmpeg的参数,我们可以指定使用不同的摄像头,并可以同时从多个摄像头获取音视频数据。 接着,我们可以使用qt的图像显示控件来显示摄像头解码得到的视频帧。可以使用qt提供的QGraphicsView、QLabel等控件,将视频帧数据转换成qt能够识别的格式并在界面上实时显示。 为了实现摄像头实时显示,我们可以在qt中使用多线程来同时处理多个摄像头的数据。可以为每个摄像头开启一个线程,用于获取该摄像头的rtsp流并解码。然后将解码得到的视频帧数据通过线程间的通信机制传递给主线程,然后在主线程中更新界面并显示视频帧。 另外,为了提高实时性,我们可以对视频帧进行硬件加速处理,比如使用OpenGL进行渲染,这样可以减少CPU的使用率,提高视频的播放效果。 总结来说,实现qt与ffmpeg结合实现摄像头实时显示功能,主要是通过ffmpeg获取rtsp流并解码,然后通过qt的图像显示控件实时显示解码得到的视频帧,在多线程中同时处理多个摄像头的数据,最终实现摄像头的实时显示效果。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值