opencv处理图像(二)

发布于:2025-05-11 ⋅ 阅读:(10) ⋅ 点赞:(0)

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

我们主线程负责图形渲染等操作,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处理 → 返回结果图像

 


网站公告

今日签到

点亮在社区的每一天
去签到