微信公众号:OpenCV开发者联盟
关注获取更多计算机视觉与深度学习知识
引言
应用程序概述
多线程协作信号触发示意图
代码实现
这样实现了三个类
ImageFetchThread // 图像采集
ImageAnalysisThread // 图像分析
ContentPanel // 界面显示与更新
这三个类的代码分别,模拟图像采集线程
1class 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
处理图像线程
1class 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
界面线程
1class 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开发者联盟,
专注各种语言的OpenCV开发教程分享
OpenCV周边开发技术应用!
扫码查看OpenCV+OpenVIO+Pytorch系统化学习路线图
推荐阅读
CV全栈开发者说 - 从传统算法到深度学习怎么修炼
2022入坑深度学习,我选择Pytorch框架!
Pytorch轻松实现经典视觉任务
教程推荐 | Pytorch框架CV开发-从入门到实战
OpenCV4 C++学习 必备基础语法知识三
OpenCV4 C++学习 必备基础语法知识二
OpenCV4.5.4 人脸检测+五点landmark新功能测试
OpenCV4.5.4人脸识别详解与代码演示
OpenCV二值图象分析之Blob分析找圆
OpenCV4.5.x DNN + YOLOv5 C++推理
OpenCV4.5.4 直接支持YOLOv5 6.1版本模型推理
OpenVINO2021.4+YOLOX目标检测模型部署测试
比YOLOv5还厉害的YOLOX来了,官方支持OpenVINO推理