VS2022+QT6.7.2+opencv 子线程捕获摄像头显示在主线程的Label中(详细)(注释)

目录

 一、方法

二、具体实现

 三、运行效果


 一、方法

实现逻辑:使用定时器捕获视频帧,在子线程中将捕获的帧构造后返回给主线程的Label中显示,然后安全的退出线程。

opencv用到的类如下:

    QImage* image = new QImage; //图像类
    VideoCapture cap; //视频流
    Mat frame; //视频帧
    
    cap.open(0); //打开默认摄像头
    cap.release(); //释放摄像头

    //从视频捕获对象cap中读取一帧视频数据,并将这帧数据存储在Mat类型的对象 frame中。
    cap.read(frame); 
    
    //获取OpenCV的cv::Mat对象frame ,转为const uchar*类型 ,得到图像数据的首地址
    const uchar* pSrc = (const uchar*)frame.data; 

   QImage qImage(pSrc, frame.cols, frame.rows, frame.step, QImage::Format_RGB888);
   //pSrc:指向原始图像数据的指针,图像数据的起始地址;
   //frame.cols:这个参数指定了图像的宽度(以像素为单位);
   //frame.rows:这个参数指定了图像的高度(以像素为单位);
   //frame.step:这个参数指定了图像中一行数据所占的字节数;
   //QImage::Format_RGB888:这个参数指定了图像数据的格式;
//目的是从一个OpenCV的cv::Mat对象(假设为frame)创建一个QImage对象,
//其中frame包含RGB格式的图像数据,没有透明度通道。

二、具体实现

 QtWidgetsApplication14.h

#pragma once

#include <QtWidgets/QMainWindow>
#include "ui_QtWidgetsApplication14.h"
#include<opencv2/opencv.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2/videoio/videoio.hpp>
#include<QTimer>
#include<QThread>
using namespace std;
using namespace cv;

class QtWidgetsApplication14 : public QMainWindow  //主界面类
{
    Q_OBJECT

public:
    QtWidgetsApplication14(QWidget *parent = nullptr);
    ~QtWidgetsApplication14();
    QTimer* timer = new QTimer(this); //定时器
    QThread* thread = new QThread(this);  //线程
    void closeEvent(QCloseEvent *event); //关闭窗口事件

public slots:
    void slot_readframe(QImage);  //槽函数,用来接收线程传过来的图像

private:
    Ui::QtWidgetsApplication14Class ui;
};

class mythread : public QObject  //线程类
{
    Q_OBJECT // 必须
public:
   mythread() //构造函数
    {
       cap.open(0); //打开摄像头
    }
   ~mythread()  //析构函数
   {
      cap.release(); //释放摄像头
   }
    void readframe();  //捕获视频帧
    VideoCapture cap; //视频流
    Mat frame; //视频帧

signals:
    void signal_readframe(QImage);  //信号,用来发送视频帧给主界面
};

 QtWidgetsApplication14.cpp

#include "QtWidgetsApplication14.h"
QtWidgetsApplication14::QtWidgetsApplication14(QWidget* parent)
    : QMainWindow(parent)
{
    ui.setupUi(this);
    mythread* myth = new mythread(); //创建线程
    myth->moveToThread(thread);  //将线程绑定到线程对象thread 注意myth已在类中创建

    //定时器捕获视频帧
    connect(timer, &QTimer::timeout, myth, &mythread::readframe);

    //子线程将捕获的视频帧返回到主界面Label中
    connect(myth, &mythread::signal_sendframe, this, &QtWidgetsApplication14::slot_readframe);

    //使用按钮开启线程与定时器
    connect(ui.pushButton, &QPushButton::clicked, this, [=]() {
        thread->start(); //线程开始
        timer->start(33); //定时器开始
        ui.label->setScaledContents(true);  //调整QPixmap的大小以匹配QLabel的大小
        });
}

void QtWidgetsApplication14::closeEvent(QCloseEvent* event)  //窗口关闭事件
{
    timer->stop();  //停止定时器
    thread->quit();  //退出线程
    thread->wait(); //等待线程真正退出 (安全)
}

void mythread::readframe() //子线程读取视频帧
{
    cap.read(frame); //读一帧
    const uchar* pSrc = (const uchar*)frame.data; //得到图像首地址

    //从一个原始图像数据(pSrc)创建一个 qImage 对象
    QImage qImage(pSrc, frame.cols, frame.rows, frame.step, QImage::Format_RGB888);

    //从RGB顺序交换到BGR顺序,返回一个新的 QImage 对象,其颜色通道已经被交换
    QImage image = qImage.rgbSwapped();

    emit signal_sendframe(image);  //发送image信号给主界面
}
void QtWidgetsApplication14::slot_readframe(QImage image)  //主界面槽函数
{
    //QPixmap pixmap = QPixmap::fromImage(image); 
    //ui.label->setPixmap(pixmap);
    //ui.label->resize(pixmap.size()); // 调整QLabel的大小以匹配QPixmap的大小
    ui.label->setPixmap(QPixmap::fromImage(image));  //将image显示在label上
}

QtWidgetsApplication14::~QtWidgetsApplication14()  //析构函数
{
}

 main.cpp

#include "QtWidgetsApplication14.h"
#include <QtWidgets/QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QtWidgetsApplication14 w;
    w.show();
    return a.exec();
}

 三、运行效果

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
flowable是一个开源的、可扩展的业务流程管理引擎。它基于Java语言开发,可以与Spring框架无缝集成。flowable6.7.2是flowable的一个版本,在该版本修复了一些已知的bug,并加入了一些新特性和改进。该版本的flowable可以在SpringBoot应用程序使用。 SpringBoot是一个能够简化Spring应用开发的框架。它使用约定优于配置的原则,通过自动化配置和快速启动来减少开发者的工作量。使用SpringBoot可以快速搭建和部署应用程序,并且可以与各种流行的开发框架和技术无缝集成。 Vue是一种用于构建用户界面的渐进式JavaScript框架。它要用于构建单页面应用程序,可以通过组件化方式构建复杂的用户界面。Vue具有简单易用、灵活、高效等特点,支持双向数据绑定和组件化的开发模式。Vue和SpringBoot可以通过RESTful API进行交互,实现前后端的分离开发。 当使用flowable6.7.2时,可以将其集成到SpringBoot应用程序,以便在应用使用业务流程管理功能。可以通过引入适当的依赖和进行配置来实现集成。同时,可以使用Vue来构建应用程序的用户界面,通过向后端发送请求和接收响应来实现与flowable的交互。可以通过调用flowable的API来管理和执行业务流程,并将结果通过RESTful API返回给前端的Vue组件进行展示和交互。 总而言之,flowable6.7.2可以与SpringBoot和Vue无缝集成,实现一个具备业务流程管理功能的应用程序。SpringBoot提供了后端的支持,Vue提供了前端的支持,而flowable则负责业务流程的管理和执行。这样的架构可以提高开发效率和应用程序的稳定性,使开发者能够更加专注于业务逻辑的实现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值