【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://www.pswp.cn/diannao/43864.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/43864.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/43864.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

SAP顧問的核心競爭力是什么?

最近看到幾個業內大佬在討論這個話題&#xff0c;我也想談談我的看法。這位大佬的原話是“SAP顧問的核心技能不是配置軟件&#xff0c;而是對財務、供應鏈、銷售等運行流程的理解&#xff0c;解決的是企業流程和數據標準化的問題。” 我先不做評價&#xff0c;我先問幾個問題。…

選擇排序(C語言版)

選擇排序是一種簡單直觀的排序算法 算法實現 首先在未排序序列中找到最小&#xff08;大&#xff09;元素&#xff0c;存放到排序序列的起始位置。 再從剩余未排序元素中繼續尋找最小&#xff08;大&#xff09;元素&#xff0c;然后放到已排序序列的末尾。 重復第二步&…

【k8s安裝redis】k8s安裝單機版redis實現高性能高可用

文章目錄 簡介一.條件及環境說明&#xff1a;二.需求說明&#xff1a;三.實現原理及說明四.詳細步驟4.1.創建configmap 配置文件4.2.創建StatefulSet 配置4.3.創建service headless 配置 五.安裝說明 簡介 本文將根據在k8s環境中搭建【偽】單機模式的redis實例。由于共享存儲的…

020-GeoGebra中級篇-幾何對象之點與向量

本文概述了在GeoGebra中如何使用笛卡爾或極坐標系輸入點和向量。用戶可以通過指令欄輸入數字和角度&#xff0c;使用工具或指令創建點和向量。在笛卡爾坐標系中&#xff0c;示例如“P(1,0)”&#xff1b;在極坐標系中&#xff0c;示例如“P(1;0)”或“v(5;90)”。文章還介紹了點…

深入理解循環神經網絡(RNN)

深入理解循環神經網絡&#xff08;RNN&#xff09; 循環神經網絡&#xff08;Recurrent Neural Network, RNN&#xff09;是一類專門處理序列數據的神經網絡&#xff0c;廣泛應用于自然語言處理、時間序列預測、語音識別等領域。本文將詳細解釋RNN的基本結構、工作原理以及其優…

uniapp本地打包到Android Studio生成APK文件

&#xff08;1&#xff09;安裝 Android Studio 軟件&#xff1b; 下載地址&#xff1a;官方下載地址&#xff0c;英文環境 安裝&#xff1a;如下之外&#xff0c;其他一鍵 next &#xff08;2&#xff09;配置java環境&#xff1b; 下載&#xff1a;j…

基于SpringBoot構造超簡易QQ郵件服務發送 第二版

目錄 追加 郵箱附件 添加依賴 編碼 測試 第二版的更新點是追加了 郵箱附件功能 ( 后期追加定時任務 ) 基于SpringBoot構造超簡易QQ郵件服務發送(分離-圖解-新手) 第一版 追加 郵箱附件 添加依賴 <!-- 電子郵件 --><dependency><groupId>org.spri…

Java小白入門到實戰應用教程-介紹篇

writer:eleven 介紹 編程語言介紹 編程語言按照抽象層次和硬件交互的方式劃分為低級編程語言和高級編程語言。 低級編程語言更接近計算機硬件層面&#xff0c;通常具有執行效率高的特點&#xff0c;但是由于注重計算機底層交互&#xff0c;所以編程難度相對較大。 高級編程…

國內開源RAG知識庫ChatWiki MaxKb QAnyThing對比

RAG 知識庫 &#xff0c; 是一個比較火的賽道&#xff0c;以下是國內開源的RAG 知識庫 ChatWiki 芝麻小客服開源的一個RAG 知識庫&#xff0c;核心特點是和人工聊天系統打通&#xff0c;可以作為對外的聊天系統使用。 開源地址 https://github.com/zhimaAi/chatwiki 云端體…

如何評價Flutter?

哈嘍&#xff0c;我是老劉 我們團隊使用Flutter已經快6年了。 有很多人問過我們對Flutter的評價。 今天在這里回顧一下6年前選擇Flutter時的原因&#xff0c;以及Flutter在這幾年中的實際表現如何。 選擇Flutter時的判斷 1、性能 最開始吸引我們的就是其優秀的性能。 特別是…

【vue3|第16期】初探Vue-Router與現代網頁路由

日期:2024年7月6日 作者:Commas 簽名:(? ?_?)? 積跬步以致千里,積小流以成江海…… 注釋:如果您覺得有所幫助,幫忙點個贊,也可以關注我,我們一起成長;如果有不對的地方,還望各位大佬不吝賜教,謝謝^ - ^ 1.01365 = 37.7834;0.99365 = 0.0255 1.02365 = 1377.4083…

力扣第226題“翻轉二叉樹”

在本篇文章中&#xff0c;我們將詳細解讀力扣第226題“翻轉二叉樹”。通過學習本篇文章&#xff0c;讀者將掌握如何使用遞歸和迭代的方法來翻轉二叉樹&#xff0c;并了解相關的復雜度分析和模擬面試問答。每種方法都將配以詳細的解釋&#xff0c;以便于理解。 問題描述 力扣第…

深入探索聯邦學習框架 Flower

聯邦學習框架 本文主要期望介紹一個設計良好的聯邦學習框架 Flower&#xff0c;在開始介紹 Flower 框架的細節前&#xff0c;先了解下聯邦學習框架的基礎知識。 作為一個聯邦學習框架&#xff0c;必然會包含對橫向聯邦學習的支持。橫向聯邦是指擁有類似數據的多方可以在不泄露…

【CVPR 2024】GART: Gaussian Articulated Template Models

【CVPR 2024】GART: Gaussian Articulated Template Models 一、前言Abstract1. Introduction2. Related Work3. Method3.1. Template Prior3.2. Shape Appearance Representation with GMM3.3. Motion Representation with Forward Skinning3.4. Reconstruct GART from Monocu…

Java--instanceof和類型轉換

1.如圖&#xff0c;Object&#xff0c;Person&#xff0c;Teacher&#xff0c;Student四類的關系已經寫出來了&#xff0c;由于實例化的是Student類&#xff0c;因此&#xff0c;與Student類存在關系的類在使用instanceof時都會輸出True&#xff0c;而無關的都會輸出False&…

負載均衡技術怎么實現的,負載均衡策略

目錄 負載均衡技術怎么實現的 負載均衡技術的實現方式 舉例說明 負載均衡策略 1. 輪詢(Round Robin) 2. 加權輪詢(Weighted Round Robin) 3. 最少連接數(Least Connections) 4. 響應時間(Response Time) 總結 負載均衡技術怎么實現的 負載均衡技術主要通過多種…

數據結構 —— Dijkstra算法

數據結構 —— Dijkstra算法 Dijkstra算法劃分集合模擬過程打印路徑 在上次的博客中&#xff0c;我們解決了使用最小的邊讓各個頂點連通&#xff08;最小生成樹&#xff09; 這次我們要解決的問題是現在有一個圖&#xff0c;我們要找到一條路&#xff0c;使得從一個頂點到另一個…

對比學習和多模態任務

1. 對比學習 對比學習&#xff08;Contrastive Learning&#xff09;是一種自監督學習的方法&#xff0c;旨在通過比較數據表示空間中的不同樣本來學習有用的特征表示。其核心思想是通過最大化同類樣本之間的相似性&#xff08;或降低它們之間的距離&#xff09;&#xff0c;同…

【Linux】網絡新兵連

歡迎來到 破曉的歷程的 博客 ??不負時光&#xff0c;不負己?? 引言 在上一篇博客中&#xff0c;我們簡單的介紹了一些Linux網絡一些比較基本的概念。本篇博客我們將開始正式學習Linux網絡套接字的內容&#xff0c;那么我們開始吧&#xff01; 1.網絡中的地址管理 大家一…

GraphRAG——一個基于圖的檢索增強生成的開源項目【送源碼】

GraphRAG 最近幾天&#xff0c;微軟團隊開源了GraphRAG&#xff0c;這是一種基于圖&#xff08;Graph&#xff09;的檢索增強生成方法。 先說說RAG吧&#xff0c;檢索增強生成&#xff0c;相當于是從一個給定好的知識庫中進行檢索&#xff0c;接入LLM模型&#xff0c;讓模型生…