【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();
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/3224016.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

mysql 5.7.44 32位 zip安装

前言 因为研究别人代码&#xff0c;他使用了5.7的 32位 mysql &#xff0c;同时最新的 8.4 64位 mysql 不能用官方lib连接。所以安装这个版本使用&#xff0c;期间有些坑&#xff0c;在这里记录一下。 下载路径 mysql官方路径&#xff1a;https://downloads.mysql.com/archi…

c++ primer plus 第15章友,异常和其他:15.1.2 友元成员函数

#c primer plus 第15章友&#xff0c;异常和其他&#xff1a;15.1.2 友元成员函数 提示&#xff1a;这里可以添加系列文章的所有文章的目录&#xff0c;目录需要自己手动添加 例如&#xff1a;15.1.2 友元成员函数 提示&#xff1a;写完文章后&#xff0c;目录可以自动生成&am…

01:简易的电动车防盗报警器

简易的电动车防盗报警器 1、震动传感器模块的使用2、使用震动传感器模块控制继电器开关3、433M无线发射接收模块的使用 需要材料&#xff1a; 1、51单片机 2、震动传感器模块 3、继电器模块 4、高功率喇叭 5、433M无线发射接收模块 6、弱干杜邦线 1、震动传感器模块的使用 接好…

2024全网最全面及最新且最为详细的网络安全技巧五 之 SSRF 漏洞EXP技巧,典例分析以及 如何修复 (下册)———— 作者:LJS

五.SSRF 漏洞EXP技巧&#xff0c;典例分析以及 如何修复 (下册) 目录 五.SSRF 漏洞EXP技巧&#xff0c;典例分析以及 如何修复 (下册) 5.4gopher 协议初探 0x01 Gopher协议 0x02 协议访问学习 复现环境 centos7 kali 2018 发送http get请求 发送http post请求 5.5 SSRF…

2017年,我成为了技术博主

2017年9月&#xff0c;我已经大三了。 >>上一篇&#xff08;爪哇&#xff0c;我初窥门径&#xff09; 我大二学了很多java技术&#xff0c;看似我一会就把javaweb/ssh/ssm这些技术栈给学了。 这些技术确实不难&#xff0c;即便是我&#xff0c;我都能学会&#xff0c;…

Java字符串(String、字符串拼接、原理)

文章目录 一、String字符串1.1创建方式【直接赋值、new一个对象】1.1.1 使用字符串字面值直接赋值&#xff1a;&#xff08;1&#xff09;字符串字面量创建String对象的转换过程&#xff08;2&#xff09;一些方法&#xff08;3&#xff09;说明 1.1.2 使用new关键字创建字符串…

新手教学系列——crontab 使用不当引发的服务器性能问题

起因及症状 最近,我们的一台服务器随着运行时间的增加,逐渐出现了压力过大的问题。具体表现为数据库连接数飙升至 4000+,Redis 频繁超时,系统报错文件打开数过多等。针对这些问题,我们逐一检查了数据库连接池、Redis 连接池以及系统的 ulimit 配置,但都未能找到问题的根…

服务注册Eureka

目录 一、背景 1、概念 2、CAP 理论 3、常见的注册中心 二、Eureka 三、搭建 Eureka Server 1、搭建注册中心 四、服务注册 五、服务发现 六、Eureka 和 Zooper 的区别 一、背景 1、概念 远程调用就类似于一种通信 例如&#xff1a;当游客与景区之间进行通信&…

Linux网络命令:网络工具socat详解

目录 一、概述 二、基本用法 1、基本语法 2、常用选项 3、获取帮助 三、用法示例 1. 监听 TCP 端口并回显接收到的数据 2. 通过 TCP 端口转发数据到 UNIX 套接字 3. 将文件内容发送到 TCP 端口&#xff1a; 4. 使用伪终端进行串行通信 5、启动一个TCP服务器 6、建…

如何借助社交媒体影响者的力量,让品牌影响力倍增?

一、引言&#xff1a;为何社交媒体影响者如此关键&#xff1f; 在信息爆炸的今天&#xff0c;社交媒体已成为塑造消费者行为与品牌认知的重要渠道。社交媒体影响者&#xff0c;凭借其在特定领域的专业知识、庞大的粉丝基础及高度的互动性&#xff0c;成为了品牌传播不可忽视的…

【鸿蒙学习笔记】属性学习迭代笔记

这里写目录标题 TextImageColumnRow Text Entry Component struct PracExample {build() {Row() {Text(文本描述).fontSize(40)// 字体大小.fontWeight(FontWeight.Bold)// 加粗.fontColor(Color.Blue)// 字体颜色.backgroundColor(Color.Red)// 背景颜色.width(50%)// 组件宽…

【LLM】三、open-webui+ollama搭建自己的聊天机器人

系列文章目录 往期文章回顾&#xff1a; 【LLM】二、python调用本地的ollama部署的大模型 【LLM】一、利用ollama本地部署大模型 目录 前言 一、open-webui是什么 二、安装 1.docker安装 2.源码安装 三、使用 四、问题汇总 总结 前言 前面的文章&#xff0c;我们已经…

【Python的pip配置、程序运行、生成exe文件】

Python的pip配置、程序运行、生成exe文件 一、安装Python 通过官网下载对应的版本&#xff0c;安装即可。 下载地址&#xff1a;https://www.python.org/downloads/ Python标准库查看&#xff08;Python自带库&#xff09; Python 标准库文档 安装Python的时候&#xff0c…

昇思25天学习打卡营第13天 | ShuffleNet图像分类

ShuffleNet网络介绍 ShuffleNetV1是旷视科技提出的一种计算高效的CNN模型&#xff0c;和MobileNet, SqueezeNet等一样主要应用在移动端&#xff0c;所以模型的设计目标就是利用有限的计算资源来达到最好的模型精度。ShuffleNetV1的设计核心是引入了两种操作&#xff1a;Pointw…

移除元素的讲解,看这篇就够了!

一&#xff1a;题目 博主本文将用指向来形象的表示下标位的移动。 二&#xff1a;思路 1&#xff1a;两个整形&#xff0c;一个start&#xff0c;一个end&#xff0c;在一开始都 0&#xff0c;即这里都指向第一个元素。 2&#xff1a;在查到val之前&#xff0c;查一个&…

01 | 基础架构:一条SQL查询语句是如何执行的?

此系列文章为极客时间课程《MySQL 实战 45 讲》的学习笔记&#xff01; 引言 在了解 SQL 查询语句如何执行之前&#xff0c;先了解下MySQL 的基本架构示意图。 MySQL 分为 Server 层和引擎层。 Server 层包括连接器、查询缓存、分析器、优化器、执行器等&#xff0c;涵盖 M…

逆向分析之电脑端如何调试一些只能手机端浏览器才可以打开的网站

手机端浏览器的指纹和电脑端浏览器的指纹是不同的,这样只在手机端浏览器运行的网站则可以检测网站是否满足手机端浏览器指纹的要求,不满足则可以进行一些反爬措施。 例如一些公众号,其实就是使用手机端浏览器打开的H5网站,就可以进行手机端浏览器指纹检测。 这里只是讲解下…

硬盘分区读不出来的危机与数据拯救指南

在数字时代&#xff0c;硬盘作为我们存储珍贵数据的“保险箱”&#xff0c;其稳定性和可访问性至关重要。然而&#xff0c;当硬盘分区突然读不出来时&#xff0c;这份安全感瞬间化为泡影&#xff0c;让人心急如焚。本文将深入探讨硬盘分区读不出来的原因、提供两种实用的数据恢…

可以添加todo清单桌面小组件的便签哪个好?

在我们快节奏的生活中&#xff0c;有效的时间管理和任务追踪是必不可少的。为了实现这一目标&#xff0c;许多人选择使用桌面便签&#xff0c;尤其是那些具有Todo清单桌面小组件的便签。但是&#xff0c;面对市场上众多选择&#xff0c;可以添加todo清单桌面小组件的便签哪个好…

springboot中@bean注解的创建和使用

bean的创建顺序 在Spring Boot中&#xff0c;当一个配置类&#xff08;使用Configuration注解的类&#xff09;中定义了多个bean时&#xff0c;这些bean的创建顺序并不完全由它们在类中的声明顺序决定。Spring框架在创建和管理bean时&#xff0c;遵循了复杂的依赖注入和生命周…