技术专栏
PyQT5开发之线程协作实现流水线式图像分析
学习多线程最典型的问题就是如何在多个线程之间传递消息与写作,PyQT5的线程支持在不同线程之间传递信号触发事件,实现多个线程之间的协助,完成诸如生产者-消费者这样经典的多线程协作。本文将通过QThread与信号槽机制构建一个生产者-消费者模型,演示多个线程之间的协作。
应用程序概述
这里演示了一个从图像采集(用本地图像数据集替代)到图像分析处理(简单二值化+形态学处理)、到主界面更新的应用程序。主界面是UI线程、图像采集跟图像分析分别在两个不同的工作线程中,通过信号与槽机制协作工作,相互配合实现图像采集到分析到结果更新到界面线程。
多线程协作信号触发示意图
代码实现
这样实现了三个类
ImageFetchThread // 图像采集
ImageAnalysisThread // 图像分析
ContentPanel // 界面显示与更新
这三个类的代码分别,模拟图像采集线程
class ImageFetchThread(QtCore.QThread):
2 fire_stats_signal = QtCore.pyqtSignal(dict)
3
4 def __init__(self, images_dir):
5 super(ImageFetchThread, self).__init__()
6 self.images_dir = images_dir
7 self.read_next = True
8
9 def request_image(self):
10 self.read_next = True
11
12 def run(self):
13 if len(self.images_dir) == 0:
14 return
15 files = os.listdir(self.images_dir)
16 idx = 0
17 while True:
18 if idx == len(files):
19 break
20 if self.read_next is True:
21 print("grab one image...")
22 image = cv.imread(os.path.join(self.images_dir, files[idx]))
23 gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
24 idx += 1
25 self.read_next = False
26 self.fire_stats_signal.emit({"im_data": gray})
27 self.fire_stats_signal.emit({"done": "done"})
28 return
处理图像线程
class ImageAnalysisThread(QtCore.QThread):
2 request_image_signal = QtCore.pyqtSignal()
3 update_result_signal = QtCore.pyqtSignal(dict)
4
5 def __init__(self):
6 super(ImageAnalysisThread, self).__init__()
7 self.image_data = None
8 self.stop = False
9
10 def process_im(self, results):
11 self.image_data = results.get("im_data")
12 if results.get("done") is not None:
13 self.stop = True
14
15 def run(self):
16 while True:
17 if self.stop is True:
18 break
19 if self.image_data is None:
20 continue
21 print("started to process one image...")
22 # ret, binary = cv.threshold(self.image_data, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)
23 binary = cv.adaptiveThreshold(self.image_data, 255, cv.ADAPTIVE_THRESH_GAUSSIAN_C,
24 cv.THRESH_BINARY_INV, 25, 10)
25 se = cv.getStructuringElement(cv.MORPH_RECT, (7, 7))
26 resutl = cv.morphologyEx(binary, cv.MORPH_DILATE, se)
27 self.request_image_signal.emit()
28 self.update_result_signal.emit({"im_data": resutl})
29 self.image_data = None
30 self.update_result_signal.emit({"done": "done"})
31 return
界面线程
class ContentPanel(QtWidgets.QWidget):
2 def __init__(self, parent=None):
3 super().__init__(parent)
4 fileBtn = QtWidgets.QPushButton("目录...")
5 self.image_files_dir= QtWidgets.QLineEdit()
6 self.image_files_dir.setMinimumWidth(100)
7 self.image_files_dir.setEnabled(False)
8 self.processBtn = QtWidgets.QPushButton("开始处理")
9 hbox_layout = QtWidgets.QHBoxLayout()
10 hbox_layout.addWidget(fileBtn)
11 hbox_layout.addWidget(self.image_files_dir)
12 hbox_layout.addWidget(self.processBtn)
13 panel1 = QtWidgets.QGroupBox("目录选择")
14 panel1.setLayout(hbox_layout)
15
16 # 图像标签
17 self.imgLabel = QtWidgets.QLabel()
18 self.imgLabel.setMinimumSize(800, 600)
19 self.imgLabel.setStyleSheet("background-color:black; color: deeppink")
20 self.imgLabel.setAlignment(QtCore.Qt.AlignCenter)
21
22 # 添加到布局管理器中
23 vbox_layout = QtWidgets.QVBoxLayout()
24 vbox_layout.addWidget(panel1)
25 vbox_layout.addWidget(self.imgLabel)
26 vbox_layout.addStretch(1)
27
28 # 面板容器
29 self.setLayout(vbox_layout)
30
31 # setup listener
32 fileBtn.clicked.connect(self.on_select_image_dir)
33 self.processBtn.clicked.connect(self.on_process)
34
35 self.fetch_thread = None
36 self.analysis_thread = None
37
38 def on_select_image_dir(self):
39 img_dir = QtWidgets.QFileDialog.getExistingDirectory(self, "图像文件夹", ".")
40 self.image_files_dir.setText(img_dir)
演示部分
演示部分
文章来源公众号:OpenCV开发者联盟
声明:本文内容由易百纳平台入驻作者撰写,文章观点仅代表作者本人,不代表易百纳立场。如有内容侵权或者其他问题,请联系本站进行删除。
红包
1
收藏
评论
打赏
- 分享
- 举报
评论
0个
手气红包
暂无数据
相关专栏
-
浏览量:505次2023-06-12 14:18:52
-
浏览量:5213次2021-06-08 22:36:45
-
浏览量:5029次2021-04-11 01:10:40
-
浏览量:1822次2019-07-04 12:02:50
-
浏览量:2237次2022-01-20 09:00:19
-
浏览量:14017次2020-12-06 17:48:56
-
浏览量:14438次2020-12-02 16:57:03
-
2024-01-11 15:44:19
-
浏览量:10764次2021-04-11 14:45:45
-
浏览量:4901次2020-11-04 09:47:48
-
浏览量:1626次2020-07-02 16:11:35
-
浏览量:872次2023-06-06 15:58:55
-
浏览量:3025次2023-03-16 10:59:43
-
浏览量:2207次2020-06-15 11:56:32
-
浏览量:2148次2020-06-18 09:34:12
-
浏览量:2207次2018-02-11 19:52:32
-
浏览量:6492次2020-10-28 23:03:59
-
浏览量:4198次2020-10-28 23:08:53
-
浏览量:21024次2020-12-10 16:21:29
置顶时间设置
结束时间
删除原因
-
广告/SPAM
-
恶意灌水
-
违规内容
-
文不对题
-
重复发帖
打赏作者
张显显
您的支持将鼓励我继续创作!
打赏金额:
¥1
¥5
¥10
¥50
¥100
支付方式:
微信支付
打赏成功!
感谢您的打赏,如若您也想被打赏,可前往 发表专栏 哦~
举报反馈
举报类型
- 内容涉黄/赌/毒
- 内容侵权/抄袭
- 政治相关
- 涉嫌广告
- 侮辱谩骂
- 其他
详细说明
审核成功
发布时间设置
发布时间:
请选择发布时间设置
是否关联周任务-专栏模块
审核失败
失败原因
请选择失败原因
备注
请输入备注