PyQt5入門以及與OpenCV的簡單整合
PyQt5與OpenCV簡介
PyQt
PyQt是Python語言的GUI程式設計解決方案之一。可以用來代替Python內建的Tkinter。其它替代者還有PyGTK、wxPython等。與Qt一樣,PyQt是一個自由軟體。
PyQt的開發者是英國的“Riverbank Computing”公司。它提供了GPL與商業協議兩種授權方式,因此它可以免費地用於自由軟體的開發。PyQt可以運行於Microsoft Windows、Mac OS X、Linux以及Unix的多數變種上。
pyqt5是一套Python繫結QT5應用的框架。它可用於Python 2和3。pyqt5的官方網站
http://www.riverbankcomputing.co.uk/news
pyqt5做為Python的一個模組,它有620多個類和6000個函式和方法。
pyqt5的類別分為幾個模組,包括以下:
QtCore
QtGui
QtWidgets
QtMultimedia
QtBluetooth
QtNetwork
QtPositioning
Enginio
QtWebSockets
QtWebKit
QtWebKitWidgets
QtXml
QtSvg
QtSql
QtTest
QtCore:包含了核心的非GUI功能。此模組用於處理時間、檔案和目錄、各種資料型別、流、URL、MIME型別、執行緒或程序。
QtGui包含類視窗系統整合、事件處理、二維圖形、基本成像、字型和文字。
qtwidgets模組包含創造經典桌面風格的使用者介面提供了一套UI元素的類。
QtMultimedia包含的類來處理多媒體內容和API來訪問相機和收音機的功能。
Qtbluetooth模組包含類的掃描裝置和連線並與他們互動。描述模組包含了網路程式設計的類。這些類便於TCP和IP和UDP客戶端和伺服器的編碼,使網路程式設計更容易和更便攜。
Qtpositioning包含類的利用各種可能的來源,確定位置,包括衛星、Wi-Fi、或一個文字檔案。
Enginio模組實現了客戶端庫訪問Qt雲服務託管的應用程式執行時。
Qtwebsockets模組包含實現WebSocket協議類。
QtWebKit包含一個基於Webkit2圖書館Web瀏覽器實現類。
Qtwebkitwidgets包含的類的基礎webkit1一用於qtwidgets應用Web瀏覽器的實現。
QtXml包含與XML檔案的類。這個模組為SAX和DOM API提供了實現。
QtSvg模組提供了顯示SVG檔案內容的類。可伸縮向量圖形(SVG)是一種描述二維圖形和圖形應用的語言。
QtSql模組提供操作資料庫的類。
QtTest包含的功能,使pyqt5應用程式的單元測試
PyQt5不相容PyQt4。PyQt5有一些巨大的改進。但是,遷移並不是很難,兩者的區別如下:
重新組合模組,一些模組已經被廢棄(QtScript),有些被分為兩個子模組(QtGui, QtWebKit)。
添加了新的模組,比如QtBluetooth, QtPositioning,和Enginio。
廢棄了SINGAL()和SLOT()的呼叫方式,使用了新的訊號和xx處理方式。
不再支援所有被標記為廢棄的或不建議使用的Qt API
OpenCV的全稱是Open Source Computer Vision Library,是一個跨平臺的計算機視覺庫。OpenCV是由英特爾公司發起並參與開發,以BSD許可證授權發行,可以在商業和研究領域中免費使用。OpenCV可用於開發實時的影象處理、計算機視覺以及模式識別程式。該程式庫也可以使用英特爾公司的IPP進行加速處理。
PyQt5 demo 3個
demo1, 簡單的GUI
#!/usr/bin/python3
# -*- coding: utf-8 -*-
"""
PyQt5 demo 1
"""
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton
# demo1繼承自QWidget
class demo1(QWidget):
# 建構函式
def __init__(self):
# 父類初始化
super().__init__()
self.init_show()
def init_show(self):
btn = QPushButton('Hello, PyQt5', self)
btn.move(300, 200)
btn.resize(100, 40)
self.setWindowTitle('demo1')
self.resize(800, 600)
# 執行
if __name__ == '__main__':
app = QApplication(sys.argv)
w = demo1()
w.show()
app.exec()
demo2, 簡單的signal與slot
#!/usr/bin/python3
# -*- coding: utf-8 -*-
"""
simple signal
"""
import sys
from PyQt5.QtWidgets import QApplication, QDialog, QPushButton
app = QApplication(sys.argv)
dlg = QDialog()
dlg.setWindowTitle('just close it')
dlg.resize(300, 200)
btn = QPushButton(dlg)
btn.resize(100, 50)
btn.setText('click it!')
btn.move(100, 100)
# 將btn的clicked訊號與dlg的close槽連線
btn.clicked.connect(dlg.close)
dlg.show()
sys.exit(app.exec())
demo3, 簡單的串列埠通訊
#!/usr/bin/python3
# -*- coding: utf-8 -*-
"""
PyQt5 demo 2
"""
# 匯入QSerialPort庫
from PyQt5.QtSerialPort import QSerialPort
from PyQt5.QtCore import QIODevice, QByteArray
port = QSerialPort('COM1')
# QSerialPort的一些通訊設定
port.setBaudRate(QSerialPort.Baud9600)
port.setFlowControl(QSerialPort.FlowControl(0))
port.setParity(QSerialPort.Parity(7))
port.setStopBits(QSerialPort.StopBits(1))
# 實際程式碼中應判斷是否開啟成功
port.open(QIODevice.ReadWrite)
byte = QByteArray()
byte.resize(6)
byte.fill('0')
port.write(byte)
port.flush()
port.close()
OpenCV demo
demo1, 簡單讀取一個image
import cv2
"""
simple opencv snippet
"""
# 讀取影象
img = cv2.imread('D:/wuhan.jpg')
# 顯示影象
cv2.imshow('wuhan', img)
# 等待鍵盤輸入事件
cv2.waitKey(0)
#銷燬所有window
cv2.destroyAllWindows()
demo2, 簡單的影象處理
import cv2
"""
simple opencv snippet 02
"""
# 讀取影象
img = cv2.imread('D:/lena.jpg', 0)
# 對影象做直方圖均衡處理
equ = cv2.equalizeHist(img)
# 採用cancy運算元進行邊緣檢測
edge = cv2.Canny(img, 50, 50)
# 顯示影象
cv2.imshow('img', img)
cv2.imshow('equ', equ)
cv2.imshow('edge', edge)
cv2.waitKey(0)
cv2.destroyAllWindows()
simple opencv snippet 02
PyQt5與OpenCV的簡單整合
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import sys
import cv2 as cv
import numpy as np
from PyQt5.QtGui import QImage, QPixmap
from PyQt5.QtWidgets import (QApplication, QDialog, QFileDialog, QGridLayout,
QLabel, QPushButton)
class win(QDialog):
def __init__(self):
# 初始化一個img的ndarray, 用於儲存影象
self.img = np.ndarray(())
super().__init__()
self.initUI()
def initUI(self):
self.resize(400, 300)
self.btnOpen = QPushButton('Open', self)
self.btnSave = QPushButton('Save', self)
self.btnProcess = QPushButton('Process', self)
self.btnQuit = QPushButton('Quit', self)
self.label = QLabel()
# 佈局設定
layout = QGridLayout(self)
layout.addWidget(self.label, 0, 1, 3, 4)
layout.addWidget(self.btnOpen, 4, 1, 1, 1)
layout.addWidget(self.btnSave, 4, 2, 1, 1)
layout.addWidget(self.btnProcess, 4, 3, 1, 1)
layout.addWidget(self.btnQuit, 4, 4, 1, 1)
# 訊號與槽連線, PyQt5與Qt5相同, 訊號可繫結普通成員函式
self.btnOpen.clicked.connect(self.openSlot)
self.btnSave.clicked.connect(self.saveSlot)
self.btnProcess.clicked.connect(self.processSlot)
self.btnQuit.clicked.connect(self.close)
def openSlot(self):
# 呼叫開啟檔案diglog
fileName, tmp = QFileDialog.getOpenFileName(
self, 'Open Image', './__data', '*.png *.jpg *.bmp')
if fileName is '':
return
# 採用opencv函式讀取資料
self.img = cv.imread(fileName, -1)
if self.img.size == 1:
return
self.refreshShow()
def saveSlot(self):
# 呼叫儲存檔案dialog
fileName, tmp = QFileDialog.getSaveFileName(
self, 'Save Image', './__data', '*.png *.jpg *.bmp', '*.png')
if fileName is '':
return
if self.img.size == 1:
return
# 呼叫opencv寫入影象
cv.imwrite(fileName, self.img)
def processSlot(self):
if self.img.size == 1:
return
# 對影象做模糊處理, 視窗設定為5x5
self.img = cv.blur(self.img, (5, 5))
self.refreshShow()
def refreshShow(self):
# 提取影象的尺寸和通道, 用於將opencv下的image轉換成Qimage
height, width, channel = self.img.shape
bytesPerLine = 3 * width
self.qImg = QImage(self.img.data, width, height, bytesPerLine,
QImage.Format_RGB888).rgbSwapped()
# 將Qimage顯示出來
self.label.setPixmap(QPixmap.fromImage(self.qImg))
if __name__ == '__main__':
a = QApplication(sys.argv)
w = win()
w.show()
sys.exit(a.exec_())
PyQt5與OpenCV的簡單整合
結語
PyQt將Qt強大的介面開發功能帶入到Python語言中,結合Python語言的特性,可方便快捷地實現程式設計人員的想法,更可以結合OpenCV庫包含的種種演算法實現對影象和視訊的處理.
原文連結:
https://www.jianshu.com/p/4993f37b43e6