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

opencv处理图像(二)

接下来进入到程序线程设计部分

我们主线程负责图形渲染等操作,OpenGL的限制,opencv技术对传入图像加以处理,输出预期图像给主线程

QThread

我之前也是在想给opencv开一个专门的线程,但经过了解有几个弊端,第一资源浪费,县城遗址占用问题,分线程并不是一致工作。第二,需要手动管理线程生命周期,频繁的创建和释放影响性能。

实现试例

// 1. 继承 QThread 并重写 run()
class WorkerThread : public QThread {Q_OBJECT
protected:void run() override {while (!isInterruptionRequested()) {// OpenCV 处理逻辑cv::Mat frame = processFrame();emit resultReady(frame); // 通过信号传递结果}}
signals:void resultReady(cv::Mat frame);
};// 2. 在主线程中启动
WorkerThread *thread = new WorkerThread;
connect(thread, &WorkerThread::resultReady, this, &MainWindow::updateGL);
thread->start();// 3. 安全停止线程
thread->requestInterruption();
thread->quit();
thread->wait();

QThreadPool+QRannable线程池技术

线程池通过设置可复用线程,有任务就调度空闲线程运行,实现了线程的复用,线程数可根据计算机的核的数量选择

QT封装了线程池,提供了一个全局的线程池函数

globalInstance()

要用的时候把对象或者函数指针丢进去。

// 定义任务类
class ImageTask : public QRunnable {
public:ImageTask(cv::Mat input, QString method) : m_input(input), m_method(method) {// 任务完成后自动删除(默认不启用)setAutoDelete(true); }void run() override {cv::Mat result = processImage(m_input, m_method);// 发送结果到主线程(通过信号槽或 invokeMethod)QMetaObject::invokeMethod(m_receiver, "updateDisplay", Qt::QueuedConnection, Q_ARG(cv::Mat, result));}private:cv::Mat m_input;QString m_method;QObject *m_receiver; // 接收结果的对象(如主窗口)
};// 提交任务到线程池
cv::Mat inputImage = ...;
QString method = "Grayscale";
ImageTask *task = new ImageTask(inputImage, method);
QThreadPool::globalInstance()->start(task);

再一个就是深拷贝的问题,从主线程把图像深拷贝到分支线程有很多弊端,我考虑优化一下逻辑,比如opencv对图像进行一些识别操作的时候会先把他转换程一个灰度图,再高斯模糊canny边缘检测等等,一些可复用的图像可不可以在主程序存下来,要用的时候通过移动语义将所有权直接传到分支线程处理,避免了一些频繁深度拷贝的问题,这是我的一些思路,有在这方面有见解的大佬可以指点一二。

方案适用性场景匹配度
QThread适合持续运行的任务(如实时视频流处理),线程生命周期长,需手动管理启停低(任务离散触发)
线程池适合短暂、离散的任务(如点击按钮触发单次处理),自动复用线程,减少开销

核心流程

主线程(UI线程):
1. 用户点击按钮 → 提交处理任务到线程池
2. 等待处理结果 → 接收结果并更新OpenGL显示线程池(工作线程):
1. 接收待处理图像和参数(如高斯模糊、灰度化)
2. OpenCV处理 → 返回结果图像

 

相关文章:

  • 进阶二:基于HC-SR04和LCD1602的超声波测距
  • 【ts】for in对象时,ts如何正确获取对应的属性值
  • sched_fair 调度:负载权重、虚拟运行时间与最小虚拟时间
  • Js 判断浏览器cookie 是否启用
  • 2025盘古石初赛WP
  • linux 开发小技巧之git增加指令别名
  • 路由策略和策略路由的区别以及配置案例
  • 用Python绘制动态彩色ASCII爱心:技术深度与创意结合
  • FHE与后量子密码学
  • 解决使用宝塔Linux部署前后端分离项目遇到的问题
  • Nakama:让游戏与应用更具互动性和即时性
  • 相机Camera日志分析之八:高通Camx HAL架构opencamera三级日志详解及关键字
  • spring中的@Inject注解详情
  • linux perf top分析系统性能
  • 深入解析JavaScript变量作用域:var、let、const全攻略
  • [架构之美]从零开始整合Spring Boot与Maven(十五)
  • upload-labs靶场通关详解:第四关
  • 【typenum】 0 配置文件(Cargo.toml)
  • SemanticSplitterNodeParser 和 Sentence-BERT 的区别和联系是什么
  • 前端敏感数据处理指南_JavaScript 加密方法全解析
  • 巴基斯坦关闭全部领空
  • 习近平出席俄罗斯纪念苏联伟大卫国战争胜利80周年庆典
  • 读图|展现城市品格,上海城市影像走进南美
  • 晶圆销量上升,中芯国际一季度营收增长近三成,净利增超1.6倍
  • 首批18位!苏联籍抗日航空英烈信息更新
  • 美联储主席:不打算先发制人地降息,将继续观望