引言
學習多線程最典型的問題就是如何在多個線程之間傳遞消息與寫作,PyQT5的線程支持在不同線程之間傳遞信號觸發事件,實現多個線程之間的協助,完成諸如生產者-消費者這樣經典的多線程協作。本文將通過QThread與信號槽機制構建一個生產者-消費者模型,演示多個線程之間的協作。
應用程序概述
這里演示了一個從圖像采集(用本地圖像數據集替代)到圖像分析處理(簡單二值化+形態學處理)、到主界面更新的應用程序。主界面是UI線程、圖像采集跟圖像分析分別在兩個不同的工作線程中,通過信號與槽機制協作工作,相互配合實現圖像采集到分析到結果更新到界面線程。
多線程協作信號觸發示意圖

代碼實現
這樣實現了三個類
ImageFetchThread // 圖像采集 ImageAnalysisThread // 圖像分析 ContentPanel // 界面顯示與更新
這三個類的代碼分別,模擬圖像采集線程
1classImageFetchThread(QtCore.QThread): 2fire_stats_signal=QtCore.pyqtSignal(dict) 3 4def__init__(self,images_dir): 5super(ImageFetchThread,self).__init__() 6self.images_dir=images_dir 7self.read_next=True 8 9defrequest_image(self): 10self.read_next=True 11 12defrun(self): 13iflen(self.images_dir)==0: 14return 15files=os.listdir(self.images_dir) 16idx=0 17whileTrue: 18ifidx==len(files): 19break 20ifself.read_nextisTrue: 21print("graboneimage...") 22image=cv.imread(os.path.join(self.images_dir,files[idx])) 23gray=cv.cvtColor(image,cv.COLOR_BGR2GRAY) 24idx+=1 25self.read_next=False 26self.fire_stats_signal.emit({"im_data":gray}) 27self.fire_stats_signal.emit({"done":"done"}) 28return
處理圖像線程
1classImageAnalysisThread(QtCore.QThread):
2request_image_signal=QtCore.pyqtSignal()
3update_result_signal=QtCore.pyqtSignal(dict)
4
5def__init__(self):
6super(ImageAnalysisThread,self).__init__()
7self.image_data=None
8self.stop=False
9
10defprocess_im(self,results):
11self.image_data=results.get("im_data")
12ifresults.get("done")isnotNone:
13self.stop=True
14
15defrun(self):
16whileTrue:
17ifself.stopisTrue:
18break
19ifself.image_dataisNone:
20continue
21print("startedtoprocessoneimage...")
22#ret,binary=cv.threshold(self.image_data,0,255,cv.THRESH_BINARY|cv.THRESH_OTSU)
23binary=cv.adaptiveThreshold(self.image_data,255,cv.ADAPTIVE_THRESH_GAUSSIAN_C,
24cv.THRESH_BINARY_INV,25,10)
25se=cv.getStructuringElement(cv.MORPH_RECT,(7,7))
26resutl=cv.morphologyEx(binary,cv.MORPH_DILATE,se)
27self.request_image_signal.emit()
28self.update_result_signal.emit({"im_data":resutl})
29self.image_data=None
30self.update_result_signal.emit({"done":"done"})
31return
界面線程
1classContentPanel(QtWidgets.QWidget):
2def__init__(self,parent=None):
3super().__init__(parent)
4fileBtn=QtWidgets.QPushButton("目錄...")
5self.image_files_dir=QtWidgets.QLineEdit()
6self.image_files_dir.setMinimumWidth(100)
7self.image_files_dir.setEnabled(False)
8self.processBtn=QtWidgets.QPushButton("開始處理")
9hbox_layout=QtWidgets.QHBoxLayout()
10hbox_layout.addWidget(fileBtn)
11hbox_layout.addWidget(self.image_files_dir)
12hbox_layout.addWidget(self.processBtn)
13panel1=QtWidgets.QGroupBox("目錄選擇")
14panel1.setLayout(hbox_layout)
15
16#圖像標簽
17self.imgLabel=QtWidgets.QLabel()
18self.imgLabel.setMinimumSize(800,600)
19self.imgLabel.setStyleSheet("background-color:black;color:deeppink")
20self.imgLabel.setAlignment(QtCore.Qt.AlignCenter)
21
22#添加到布局管理器中
23vbox_layout=QtWidgets.QVBoxLayout()
24vbox_layout.addWidget(panel1)
25vbox_layout.addWidget(self.imgLabel)
26vbox_layout.addStretch(1)
27
28#面板容器
29self.setLayout(vbox_layout)
30
31#setuplistener
32fileBtn.clicked.connect(self.on_select_image_dir)
33self.processBtn.clicked.connect(self.on_process)
34
35self.fetch_thread=None
36self.analysis_thread=None
37
38defon_select_image_dir(self):
39img_dir=QtWidgets.QFileDialog.getExistingDirectory(self,"圖像文件夾",".")
40self.image_files_dir.setText(img_dir)
演示部分



審核編輯:湯梓紅
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。
舉報投訴
-
多線程
+關注
關注
0文章
279瀏覽量
21025 -
應用程序
+關注
關注
38文章
3344瀏覽量
60248 -
OpenCV
+關注
關注
33文章
652瀏覽量
44778 -
圖像分析
+關注
關注
0文章
82瀏覽量
19228 -
pyqt5
+關注
關注
0文章
25瀏覽量
3628
原文標題:PyQT5+OpenCV多線程協作演示
文章出處:【微信號:CVSCHOOL,微信公眾號:OpenCV學堂】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
熱點推薦
Java多線程的用法
本文將介紹一下Java多線程的用法。 基礎介紹 什么是多線程 指的是在一個進程中同時運行多個線程,每個線程都可以獨立執行不同的任務或操作。 與單線程
可視可交互!H618上用OpenCV讀取圖像顯示到PyQt5窗口上
這里分享一個代碼,功能是使用圖像處理庫opencv從攝像頭獲取數據,縮放后從pyqt5的窗口中顯示出來。安裝opencvsudo pip3 install opencv-python創建一個
發表于 01-10 09:55
多線程好還是單線程好?單線程和多線程的區別 優缺點分析
摘要:如今單線程與多線程已經得到普遍運用,那么到底多線程好還是單線程好呢?單線程和多線程的區別又
發表于 12-08 09:33
?8.3w次閱讀
mfc多線程編程實例及代碼,mfc多線程間通信介紹
摘要:本文主要以MFC多線程為中心,分別對MFC多線程的實例、MFC多線程之間的通信展開的一系列研究,下面我們來看看原文。
發表于 12-08 15:23
?1.8w次閱讀
什么是多線程編程?多線程編程基礎知識
摘要:多線程編程是現代軟件技術中很重要的一個環節。要弄懂多線程,這就要牽涉到多進程。本文主要以多線程編程以及多線程編程相關知識而做出的一些結論。
發表于 12-08 16:30
?1.7w次閱讀
PyQT多線程正確的調用方式
我這兩天一直想把YOLOv5上加個訓練的界面,把控制臺的輸出重定向到一個PyQT5寫的界面上,然后我很順序的寫好了一個簡單的測試,發現可以重定向了,一直實時獲取輸出了。
PyQT5+OpenCV開發的應用如何打包發布?
我自己用PyQT5寫了一個應用程序,基本上都寫好了,到了打包發布這個環節,我知道的有兩個工具可以幫我打包分別是。
OpenCV+PyQT5開發桌面應用幾個重要的坑與解決
大概去年八月份的時候,我打算用OpenCV+PyQT5開發一套OpenCV教學演示與快速驗證桌面軟件,說實話那個時候我對PyQT5的理解就是Hello World水平。經過一年多開發錘
如何實現YOLOv8 + ONNRUNTIME推理界面化與多線程支持
2023年一月份跟二月份創建了一個PyQT5人工智能軟件開發系列的文章系列,過去的兩個月都沒怎么更新,心里一直想有時間繼續更新下去,今天又更新了一篇,基于PyQT5實現多線程、界面化、YOLOv8對象檢測、實例分割、姿態評估的推
多線程事務怎么回滾?一個簡單示例演示多線程事務
在spring中可以使用@Transactional注解去控制事務,使出現異常時會進行回滾,在多線程中,這個注解則不會生效,如果主線程需要先執行一些修改數據庫的操作,當子線程在進行處理出現異常時,主
發表于 08-09 12:22
?2243次閱讀
基于PyQT5與ONNXRUNTIME實現風格遷移應用
2023年一月份跟二月份創建了一個PyQT5人工智能軟件開發系列的文章系列,過去的兩個月都沒怎么更新,心里一直想有時間繼續更新下去,今天又更新了一篇,基于PyQT5實現多線程、界面化、風格遷移模型的實時推理。
多線程如何保證數據的同步
多線程編程是一種并發編程的方法,意味著程序中同時運行多個線程,每個線程可獨立執行不同的任務,共享同一份數據。由于多線程并發執行的特點,會引發數據同步的問題,即保證多個
java實現多線程的幾種方式
了多種實現多線程的方式,本文將詳細介紹以下幾種方式: 1.繼承Thread類 2.實現Runnable接口 3.Callable和Future 4.線程池 5.Java 8中
PyQT5+OpenCV多線程協作演示
評論