qt-opencv图像增强之边缘检测(多线程)
1 .pro项目文件配置
INCLUDEPATH += /usr/local/include \
/usr/local/include/opencv
/usr/local/include/opencv2
LIBS += /usr/local/lib/libopencv_* \
2 ui设计
左边是Canny边缘检测结果,右边是 L a p l a c e Laplace Laplace算子(梯度的散度)结果,分别用QLabel显示图像。下面是两个QPushButton,参考运行结果。
3 多线程逻辑
几个重要的点:
- 附属于子线程的对象,其函数在子线程中运行。需要使用信号槽使该函数运行,主线程直接调用会在主线程运行。
- 子线程中重写的void run()方法,在子线程中运行。
- 通过信号槽机制传递参数,将参数从信号所属的对象,传递到槽所属对象。
- 更好的设计是,将ui与数据的处理使用不同线程完成。
这里使用第一条,即将对象附属到子线程。
括号中…点表示携带参数,对于Mat类型这里传递的是指针,传引用时失败了。
- 定义两个子类:
基类–>子类
QThread–>MyThread,MyThread类中不重写run()函数,也不添加信号和槽等,默认的即可。
QObject–>Worker,Worker类中写要处理的事务。 - mainwindow中,点击“打开摄像头”按钮后的主要流程:
(1) MyThread线程类对象启动线程start()
(2) mainwindow对象发送operate(…)信号
(3) Worker类对象接受到信号后,执行task(…)事务
(4) MyThread线程类对象wait()阻塞主线程,等待MyThread子线程任务完成。
(5) 回到(2)
4 Canny边缘检测和Laplace算子
4.1 Canny边缘检测
Canny, J. “A Computational Approach To Edge Detection”(《一种边缘检测的计算方法》). IEEE Trans. Pattern Analysis and Machine Intelligence. 1986, (8): 679–714
4.2 L a p l a c e Laplace Laplace算子
二阶微分算子,定义为梯度的散度。具有各向同性
△ f = ▽ ∙ ▽ f = ∂ 2 f ∂ x 2 + ∂ 2 f ∂ y 2 \bigtriangleup f= \bigtriangledown \bullet \bigtriangledown f= \frac{\partial ^2f}{\partial x^2}+\frac{\partial ^2f}{\partial y^2} △f=▽∙▽f=∂x2∂2f+∂y2∂2f
离散后,对应的卷积核为
0 | 1 | 0 |
1 | -4 | 1 |
0 | 1 | 0 |
5 主要代码
worker.cpp如下