OpenCV能夠處理圖像、視頻、深度圖像等各種類型的視覺數據,在某些情況下,盡管OpenCV可以顯示窗口,但PyQt5可能更適合用于創建復雜的交互式應用程序,而自帶GPU的H618就成為了這些圖像顯示的最佳載體。
本文將實現的功能是使用圖像處理庫OpenCV從攝像頭獲取數據,縮放后從PyQt5的窗口中顯示出來。
創建pyqt5窗口
這里在電腦上使用designer軟件,創建一個Main Window類型窗體。從左邊組件欄中拖出一個label放到窗口中間。
點一下放在窗口中的label,在軟件右下角的屬性編輯器里可以設置很多東西,這里就不細介紹了。這里我是設置了QFrame啟用了邊框,QLabel中的texte屬性控制顯示的文本,QLabel中的alignment屬性控制文本對齊方式。
然后保存為.ui結尾的文件:
隨后將designer繪制的ui文件轉化為py文件
python3 -m PyQt5.uic.pyuic ui_main.ui -o ui_main.py
接下來編寫main.py程序,調用剛剛畫的窗口進行顯示,先把剛剛的ui_main.py以及一些qt庫給import進來:
from ui_main import Ui_MainWindow import PyQt5 from PyQt5 import QtCore, QtGui, QtWidgets from PyQt5.QtCore import * from PyQt5.QtGui import * # 修正qt的plugin路徑,因為某些程序(cv2)會將其改到其他路徑 import os os.environ['QT_QPA_PLATFORM_PLUGIN_PATH'] = os.path.dirname(PyQt5.__file__)
放入一點輔助代碼,一個是為了實現從遠程命令行運行qt程序顯示到桌面上,一個是為了在命令行下可以按ctrl+c快捷鍵來強制退出qt程序
#【可選代碼】允許遠程運行 import os os.environ["DISPLAY"] = ":0.0" #【建議代碼】允許終端通過ctrl+c中斷窗口,方便調試 import signal signal.signal(signal.SIGINT, signal.SIG_DFL) timer = QtCore.QTimer() timer.start(100) # You may change this if you wish. timer.timeout.connect(lambda: None) # Let the interpreter run each 100 ms
加上調用函數進行顯示的部分,這個顯示pyqt5窗口的基本程序就完成了
# 初始化窗口 import sys app = QtWidgets.QApplication(sys.argv) window = WINDOW() ui = Ui_MainWindow() ui.setupUi(window) window.showFullScreen() #全屏顯示 # window.show() #按繪制時的尺寸顯示 sys.exit(app.exec_())
在核桃派lcd屏上的效果展示
OpenCV圖像讀取及顯示
調用頭文件,opencv的頭文件只需要這一個
import cv2
打開攝像頭,其中傳入的參數1是攝像頭編號,一般是從0開始往后排
cap = cv2.VideoCapture(1)
從攝像頭讀取一幀圖像,ret是讀取狀態,frame是圖像數據
ret, frame = cap.read()
cap.read函數讀到的是bgr格式的,為了把opencv的圖像數據顯示到qt的label,需要先轉為rgb格式,并將圖像轉為Qt中用來表示圖像的QImage。
rgbImage = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) h, w, ch = rgbImage.shape qtImage = QImage(rgbImage.data, h, w, ch*w, QtGui.QImage.Format_RGB888)
label的setPixmap方法可以圖像數據覆蓋label
label.setPixmap(QPixmap.fromImage(qtImage))
顯示效果
線程,信號與槽
原代碼為了簡單,沒有使用信號槽機制,不夠線程安全,我們這里使用qt自帶的多線程功能,他的使用很簡單,只需要創建一個類并繼承自QThread, 然后將要運行的東西寫到類里的run方法下面。實例化一個對象后,調用start方法即可創建新線程
class Work(QThread): def run(self): pass work = Work() work.start()
直接在線程內調用函數去修改qt窗口的內容,不能滿足線程安全。
我們需要創建一個信號,把修改qt窗口的語句寫到一個槽內,連接他們,在想修改窗口時發出信號,讓qt內部去調度,防止跟其他qt內部的線程發生沖突。
因為我們這個線程類繼承自QThread,所以可以在類內定義信號。只需要實例化一個pyqtSignal對象即可,調用時括號內的參數決定了槽函數必須有什么類型的參數,以及發送信號時需要傳入什么參數。
signal_update_label = pyqtSignal( QPixmap)
槽函數就是隨便定義一個函數,只要函數參數跟信號一樣就行。
label:QLabel def sloat_update_label( self, pixmap:QPixmap): self.label.setPixmap(pixmap)
使用emit方法即可發送信號,qt內部會進行調度,將所有連接到本信號的函數都調出來運行,并將參數傳給他們。這是qt實現線程安全的重要機制。
self.signal_update_label.emit(QPixmap.fromImage(qtImage))
本文轉載自:https://forum.walnutpi.com/t/topic/84
審核編輯:劉清
-
RGB
+關注
關注
4文章
798瀏覽量
58394 -
OpenCV
+關注
關注
30文章
628瀏覽量
41273 -
pyqt5
+關注
關注
0文章
25瀏覽量
3394
原文標題:可視可交互!H618上用OpenCV讀取圖像顯示到PyQt5窗口上
文章出處:【微信號:gh_79acfa3aa3e3,微信公眾號:全志在線】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論