【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_OBJECT

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

软考-系统架构设计师[九年]上岸感想

2016年就开始参系统架构设计师的考试了&#xff0c;经历七次考试终于成功上岸&#xff0c;分享下自己这么多次考试失败的经验&#xff0c;希望大家可以少踩坑&#xff0c;一次通过考试 重点 如果你不想继续读下去&#xff0c;看完这段就行。 1.一定要知道最新的考试范围&…

微软清华提出全新预训练范式,指令预训练让8B模型实力暴涨!实力碾压70B模型

现在的大模型训练通常会包括两个阶段&#xff1a; 一是无监督的预训练&#xff0c;即通过因果语言建模预测下一个token生成的概率。该方法无需标注数据&#xff0c;这意味着可以利用大规模的数据学习到语言的通用特征和模式。 二是指令微调&#xff0c;即通过自然语言指令构建…

解决C++编译时的产生的skipping incompatible xxx 错误

问题 我在编译项目时&#xff0c;产生了一个 /usr/bin/ld: skipping incompatible ../../xxx/ when searching for -lxxx 的编译错误&#xff0c;如下图所示&#xff1a; 解决方法 由图中的错误可知&#xff0c;在编译时&#xff0c;是能够在我们指定目录下的 *.so 动态库的…

剪辑抽帧技巧有哪些 剪辑抽帧怎么做视频 剪辑抽帧补帧怎么操作 剪辑抽帧有什么用 视频剪辑哪个软件好用在哪里学

打破视频节奏&#xff0c;让作品告别平庸。抽帧剪辑可以改变视频叙事节奏&#xff0c;人为制造冲突、转折、卡顿的效果。这种剪辑方式&#xff0c;不仅可以推进剧情发展&#xff0c;还能吸引观众的注意力&#xff0c;有效防止观影疲劳。有关剪辑抽帧技巧有哪些&#xff0c;剪辑…

大数据基础:Hadoop之HDFS重点架构原理

文章目录 Hadoop之HDFS重点架构原理 一、什么是Hadoop 二、HDFS简介 三、HDFS架构 3.1、NameNode 3.2、SecondaryNameNode 3.3、DataNode 3.4、Client 四、fsimage和editslog合并 五、Block副本放置策略 六、读写流程 6.1、HDFS写文件流程 6.2、HDFS读文件流程 Ha…

小试牛刀--对称矩阵压缩存储

学习贺利坚老师对称矩阵压缩存储 数据结构实践——压缩存储的对称矩阵的运算_计算压缩存储对称矩阵 a 与向量 b 的乘积-CSDN博客 本人解析博客 矩阵存储和特殊矩阵的压缩存储_n阶对称矩阵压缩-CSDN博客 版本更新日志 V1.0: 对老师代码进行模仿 , 我进行名字优化, 思路代码注释 …

主流电商平台营销中大数据的应用◆

随着经济的不断发展&#xff0c;网络信息技术不断加强&#xff0c;电子商务和大数据的蓬勃发展极大地方便了人们的生活。本文章主要阐述大数据分析与电商营销的含义、大数据分析在电子商务营销中的应用&#xff0c;以及该应用的作用和存在哪些不足及解决方法。探究大数据分析在…

数据库基础复习

数据库简介 关系型数据库&#xff1a;Mysql 、Oracle 、SqlServer.... DB2 达梦 非关系型数据库&#xff1a;Redis 、MongoDB... MySQL是一个关系型数据库管理系统&#xff0c;由瑞典MySQL AB 公司开发&#xff0c;属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管…

TPM (Trusted Platform Module)发展历史『机密计算、隐私计算』

文章目录 TPM分析笔记&#xff08;一&#xff09; TPM历史TPM的历史为什么选择用TPM&#xff1f; TPM 1.1b到1.2的发展历史TPM 1.1bTPM 1.2 TPM由1.2发展到2.0版本安全需求变化TPM 2.0的设计改进 TPM 2.0规范的开发历程TPM的标准TPM的常见用途发展历程小结 TPM分析笔记&#xf…

平安养老险安徽分公司“7·8保险宣传”走进企业

近日&#xff0c;平安养老保险股份有限公司&#xff08;以下简称“平安养老险”&#xff09;安徽分公司以“78全国公众宣传日”“保险&#xff0c;让每一步前行更有底气”为主题&#xff0c;走进某大型企业开展消费者权益保护专题教育宣传活动。 本次活动旨在向企业员工普及金…

【自学网络安全】:安全策略与用户认证综合实验

实验拓扑图&#xff1a; 实验任务&#xff1a; 1、DMZ区内的服务器&#xff0c;办公区仅能在办公时间内(9:00-18:00)可以访问&#xff0c;生产区的设备全天可以访问 2、生产区不允许访问互联网&#xff0c;办公区和游客区允许访问互联网 3、办公区设备10.0.2.10不允许访问Dmz区…

KIVY Button¶

Button — Kivy 2.3.0 documentation Button Jump to API ⇓ Module: kivy.uix.button Added in 1.0.0 The Button is a Label with associated actions that are triggered when the button is pressed (or released after a click/touch). To configure the button, the s…

HTML【详解】表格 table 标签(table的属性,语义化表格,简易表格,合并单元格)

html 中的表格 <table> 由行 <tr> 组成&#xff0c;每行由单元格 <td> 组成。 所以表格是由行组成&#xff08;行由列组成&#xff09;&#xff0c;而不是由行和列组成。 table 标签 display: table &#xff0c;属于块级元素。 table 的属性 border&#…

基于Java+SpringMvc+Vue技术的智慧校园系统设计与实现

博主介绍&#xff1a;硕士研究生&#xff0c;专注于信息化技术领域开发与管理&#xff0c;会使用java、标准c/c等开发语言&#xff0c;以及毕业项目实战✌ 从事基于java BS架构、CS架构、c/c 编程工作近16年&#xff0c;拥有近12年的管理工作经验&#xff0c;拥有较丰富的技术架…

5G(NR) NTN 卫星组网架构

5G(NR) NTN 卫星组网架构 参考 3GPP TR 38.821 5G NTN 技术适用于高轨、低轨等多种星座部署场景&#xff0c;是实现星地网络融合发展的可行技术路线。5G NTN 网络分为用户段、空间段和地面段三部分。其中用户段由各种用户终端组成&#xff0c;包括手持、便携站、嵌入式终端、车…

uniapp内置组件uni.navigateTo跳转后页面空白问题解决

文章目录 导文空白问题 导文 在h5上跳转正常 但是在小程序里面跳转有问题 无任何报错 页面跳转地址显示正确&#xff0c;但页面内容为空 空白问题 控制台&#xff1a; 问题解决&#xff1a; 方法1&#xff1a; 可能是没有注册的问题&#xff0c;把没注册的页面 注册一下。 方…

互助学习平台小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;学生管理&#xff0c;课程信息管理&#xff0c;课程分类管理&#xff0c;课程评价管理&#xff0c;学习计划管理&#xff0c;留言板管理 微信端账号功能包括&#xff1a;系统首页&#xff0c;课程信息…

离线运行Llama3:本地部署终极指南_liama2 本地部署

4月18日&#xff0c;Meta在官方博客官宣了Llama3&#xff0c;标志着人工智能领域迈向了一个重要的飞跃。经过笔者的个人体验&#xff0c;Llama3 8B效果已经超越GPT-3.5&#xff0c;最为重要的是&#xff0c;Llama3是开源的&#xff0c;我们可以自己部署&#xff01; 本文和大家…

智能眼镜火热发展 AI+AR或将成为主流趋势?

日前&#xff0c;The Verge 发布消息称&#xff0c;AI 智能音频眼镜 Ray-Ban Meta 的销量可能已突破 100 万。Meta 在博客中也指出&#xff0c;Ray-Ban Meta 取得了超预期的市场表现&#xff0c;眼镜的销售速度比生产速度还要快&#xff0c;目前团队正着手于推出更多新款式。Ra…

产品推荐| 立錡低耗电器件:线性稳压器、Buck 和 Boost 转换器

想让电池用得更久、利用好它的每一份电力&#xff1f;低静态电流的电源转换器是你的必然选择。立錡深谙电源管理之道&#xff0c;为你备好了低耗电的各种产品&#xff0c;其中包括低压差线性稳压器、Buck 转换器和 Boost 转换器&#xff0c;最低消耗仅有 360nA&#xff0c;是无…