当前位置: 首页 > news >正文

【QT中实现摄像头播放、以及视频录制】

学习分享

  • 1、效果图
  • 2、camerathread.h
  • 3、camerathread.cpp
  • 4、mainwindow.h
  • 5、mainwindow.cpp
  • 6、main.cpp

1、效果图

在这里插入图片描述

2、camerathread.h

#ifndef CAMERATHREAD_H
#define CAMERATHREAD_H#include <QObject>
#include <QThread>
#include <QDebug>
#include <QImage>
#include <unistd.h>
#include <iostream>
#include <QDateTime>
#include <opencv2/opencv.hpp>
using namespace  std;
using namespace  cv;
class CameraThread :public QThread
{Q_OBJECT
public:static CameraThread *camerathread;static CameraThread *getInstance();void run();bool getIsRun() const;void setIsRun(bool value);int getFrame_width() const;int getFrame_height() const;void detecCarDaw(Mat &frame,CascadeClassifier &cascade,double scale);bool getIsStop() const;void setIsStop(bool value);bool getIsRecord() const;void setIsRecord(bool value);VideoWriter getWriter() const;bool getIsPersistent() const;void setIsPersistent(bool value);bool getIsRun_s() const;void setIsRun_s(bool value);
signals:void sendQImage(Mat frame);
private:CameraThread();CascadeClassifier cascade;//级联分类器的过滤器VideoCapture cap;Mat frame;VideoWriter writer;//OpenCV视频录制类bool isRun;//控制线程是否运行int frame_width;int frame_height;int recordNum; //录制帧率,设定为300帧bool isRun_s; //控制线程是否运行bool isStop; //控制线程结束bool isRecord; //控制线程是否开始录制bool isPersistent;
};#endif // CAMERATHREAD_H

3、camerathread.cpp

#include "camerathread.h"CameraThread * CameraThread::camerathread =nullptr;
CameraThread * CameraThread::getInstance()
{if(CameraThread::camerathread ==nullptr){CameraThread::camerathread =new CameraThread ();}return CameraThread::camerathread;
}
CameraThread::CameraThread()
{this->isRun =true;cap.open(0);// 获取摄像头的宽度和高度this->frame_width = static_cast<int>(cap.get(CAP_PROP_FRAME_WIDTH));this->frame_height = static_cast<int>(cap.get(CAP_PROP_FRAME_HEIGHT));// 定义视频编码格式、帧率和画面尺寸int fourcc = VideoWriter::fourcc('X', 'V', 'I', 'D');Size frameSize(frame_width, frame_height);this->isRun_s=false;this->isStop=false;this->isRecord=false;this->isPersistent=false;this->recordNum=0;}bool CameraThread::getIsStop() const
{return isStop;
}void CameraThread::setIsStop(bool value)
{isStop = value;
}bool CameraThread::getIsRecord() const
{return isRecord;
}void CameraThread::setIsRecord(bool value)
{isRecord = value;if(this->isRecord == false && writer.isOpened()){qDebug()<<"手动关闭"<<endl;writer.release();this->recordNum =0;}
}VideoWriter CameraThread::getWriter() const
{return writer;
}bool CameraThread::getIsPersistent() const
{return isPersistent;
}void CameraThread::setIsPersistent(bool value)
{isPersistent = value;
}bool CameraThread::getIsRun_s() const
{return isRun_s;
}void CameraThread::setIsRun_s(bool value)
{isRun_s = value;
}
void CameraThread::detecCarDaw(Mat &frame, CascadeClassifier &cascade, double scale)
{//灰度处理Mat gray;cvtColor(frame,gray,CV_BGR2GRAY);//将灰度图缩小一半//cvRound()用于四舍五入       CV_8UC1:单通道Mat smalling(cvRound(frame.rows/scale),cvRound(frame.cols/scale),CV_8UC1);//resize()改变大小      INTER_LINEAR 等比例缩小resize(gray,smalling,smalling.size(),0,0,INTER_LINEAR);//直方图均衡化:利用直方图函数将图像黑白分明  (结果跟二值化类似)equalizeHist(smalling,smalling);//进行模型检测vector<Rect>cars;cascade.detectMultiScale(smalling,cars,1.1,2,0|CV_HAAR_SCALE_IMAGE,Size(30,30));//绘制边框vector<Rect>::const_iterator iter;//系统默认迭代器for(iter =cars.begin();iter!=cars.end();iter++){rectangle(frame,//原图cvPoint(cvRound(iter->x*scale),cvRound(iter->y*scale)),//左上角坐标cvPoint(cvRound((iter->x+iter->width)*scale),cvRound((iter->y+iter->height)*scale)),//右下角坐标Scalar(0,255,0),//绿色2,//像素大小8//亮度);}
}int CameraThread::getFrame_height() const
{return frame_height;
}int CameraThread::getFrame_width() const
{return frame_width;
}bool CameraThread::getIsRun() const
{return isRun;
}void CameraThread::setIsRun(bool value)
{isRun = value;
}
void CameraThread::run()
{cascade.load("D:/OpenCV/cars.xml");//识别级联分类器  车辆while(this->isRun ==true){if(cap.read(frame)){cvtColor(frame,frame,CV_BGR2RGB);detecCarDaw(frame,cascade,2);emit sendQImage(frame);if(this->isStop ==false)//控制线程结束{if(this->isRun_s == true)//控制线程是否运行{if(cap.read(frame)){if(this->isRecord==true){if(this->recordNum ==0){QDateTime current_date_time =QDateTime::currentDateTime();QString current_date =current_date_time.toString("yyyy-MM-dd-hh-mm-ss");//QString filename ="../data/"+current_date+".avi";QString filename ="D:/Qtsoft/videoDemo/data/"+current_date+".avi";qDebug()<<"filename="<<filename;writer.open(filename.toStdString().c_str(),CV_FOURCC('M','J','P','G'),30.0,Size(frame.cols,frame.rows),true);}if(!writer.isOpened()){qDebug()<<"录制路径失败!!!"<<endl;}else{if(this->recordNum<300){//当前帧不等于总帧数,录制300帧还没有结束//qDebug()<<"录制中..."<<endl;writer<<frame;this->recordNum++;}else{qDebug()<<"已经到300帧结束录制";writer.release();this->recordNum =0;if(this->isPersistent==true){this->isRecord =true;}else if(this->isPersistent ==false){this->isRecord =false;}}}}cvtColor(frame,frame,CV_BGR2RGB);}msleep(10);}}}}}

4、mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>
#include "camerathread.h"
namespace Ui {
class MainWindow;
}class MainWindow : public QMainWindow
{Q_OBJECTpublic:explicit MainWindow(QWidget *parent = nullptr);~MainWindow();void paintEvent(QPaintEvent * Eevent);
private:Ui::MainWindow *ui;CameraThread *ct;
//    VideoThread *vt;QImage image;Mat frame;
private slots:void isChecked(Mat frame);void on_pushButton_clicked();void on_checkBox_clicked(bool checked);
};#endif // MAINWINDOW_H

5、mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{ui->setupUi(this);this->ct =CameraThread::getInstance();connect(this->ct,SIGNAL(sendQImage(Mat)),this,SLOT(isChecked(Mat)),Qt::BlockingQueuedConnection);this->ct->start();
//    this->vt =new VideoThread(0);
//    this->vt->start();waitKey(40);
}MainWindow::~MainWindow()
{delete ui;
}void MainWindow::paintEvent(QPaintEvent *Eevent)
{ui->label->setPixmap(QPixmap::fromImage(this->image));QImage q_image = QImage(frame.data,frame.cols,frame.rows,QImage::Format_RGB888);ui->label->setPixmap(QPixmap::fromImage(q_image));ui->label->setScaledContents(true);
}void MainWindow::isChecked(Mat frame)
{this->image =QImage(frame.data,frame.cols,frame.rows,QImage::Format_RGB888);this->image = this->image.scaled(ui->label->width(),ui->label->height());//以UI中的界面大小进行等比例缩放this->frame = frame.clone();this->update();
}void MainWindow::on_pushButton_clicked()
{if(this->ct->getWriter().isOpened()){qDebug()<<"已经有录制项目:请先结束录制,再操作";return;}this->ct->setIsRun_s(true);this->ct->setIsRecord(true);}void MainWindow::on_checkBox_clicked(bool checked)
{if(checked==true){//qDebug()<<"true";this->ct->setIsRecord(true);this->ct->setIsPersistent(true);}else if(checked==false){//qDebug()<<"false";this->ct->setIsPersistent(false);}
}

6、main.cpp

#include "mainwindow.h"
#include <QApplication>int main(int argc, char *argv[])
{QApplication a(argc, argv);MainWindow w;w.show();return a.exec();
}

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Consul与CoreDNS的对比
  • 架构设计(2)云原生架构与实例部署
  • 【WebGIS平台】传统聚落建筑科普数字化建模平台
  • MySQL之基本查询(上)-表的增删查改
  • 如何使用 Puppeteer 避免机器人检测?
  • oracle索引字段存储数据过长,导致索引失效
  • 突破传统,实时语音技术的革命。Livekit 开源代理框架来袭
  • for循环中list触发fast-fail或不触发的原理和方法
  • windows@windows设备之间远程命令行控制方案@windows设备间使用OpenSSH
  • C语言力扣刷题12——合并区间[排序]
  • 继承关系中的访问控制
  • 实战 | YOLOv8使用TensorRT加速推理教程(步骤 + 代码)
  • Python股票计算小程序(字符串格式化练习)
  • UE5 04-重新加载当前场景
  • c++内存管理(上)
  • [ JavaScript ] 数据结构与算法 —— 链表
  • 【comparator, comparable】小总结
  • Cumulo 的 ClojureScript 模块已经成型
  • Flannel解读
  • Hibernate最全面试题
  • javascript 哈希表
  • JS进阶 - JS 、JS-Web-API与DOM、BOM
  • Nacos系列:Nacos的Java SDK使用
  • node 版本过低
  • PHP的类修饰符与访问修饰符
  • Python利用正则抓取网页内容保存到本地
  • SpingCloudBus整合RabbitMQ
  • SQLServer之创建显式事务
  • vue的全局变量和全局拦截请求器
  • Webpack 4x 之路 ( 四 )
  • 阿里云容器服务区块链解决方案全新升级 支持Hyperledger Fabric v1.1
  • 从0实现一个tiny react(三)生命周期
  • 关于Java中分层中遇到的一些问题
  • 观察者模式实现非直接耦合
  • 类orAPI - 收藏集 - 掘金
  • 如何用Ubuntu和Xen来设置Kubernetes?
  • 世界上最简单的无等待算法(getAndIncrement)
  • 微信小程序填坑清单
  • 一个SAP顾问在美国的这些年
  • 优秀架构师必须掌握的架构思维
  • ​字​节​一​面​
  • %@ page import=%的用法
  • (2024,RWKV-5/6,RNN,矩阵值注意力状态,数据依赖线性插值,LoRA,多语言分词器)Eagle 和 Finch
  • (3)llvm ir转换过程
  • (Spark3.2.0)Spark SQL 初探: 使用大数据分析2000万KF数据
  • (笔试题)合法字符串
  • (不用互三)AI绘画工具应该如何选择
  • (第30天)二叉树阶段总结
  • (附源码)spring boot网络空间安全实验教学示范中心网站 毕业设计 111454
  • (力扣题库)跳跃游戏II(c++)
  • (详细版)Vary: Scaling up the Vision Vocabulary for Large Vision-Language Models
  • .Net Framework 4.x 程序到底运行在哪个 CLR 版本之上
  • .Net mvc总结
  • .NET分布式缓存Memcached从入门到实战
  • .NET上SQLite的连接