opencv 结合pyqt5 编写简单的图像处理GUI程序 |
您所在的位置:网站首页 › opencv的gui界面 › opencv 结合pyqt5 编写简单的图像处理GUI程序 |
实验目标
安装pyqt5: pip install pyqt5 我推荐使用Qt Designer来设计界面,如果你装的是Anaconda的话,就已经自带了designer.exe,例如我的是在:D:\ProgramData\Anaconda3\Library\bin\,如果是普通的Python环境,则需要自行安装: pip install pyqt5-tools 安装完成后,designer.exe在Python安装目录下:xxx\Lib\site-packages\pyqt5_tools\。 可以使用下面的代码生成一个简单的界面: import sys from PyQt5.QtWidgets import QApplication, QWidget if __name__ == '__main__': app = QApplication(sys.argv) window = QWidget() window.setWindowTitle('Hello World!') window.show() sys.exit(app.exec_())根据我们的挑战内容,解决思路是使用Qt Designer来设计界面,使用Python完成代码逻辑。打开designer.exe,会弹出创建新窗体的窗口,我们直接点击“create”:
我们知道GUI是通过事件驱动的,什么意思呢?比如前面我们已经设计好了界面,接下来就需要实现”打开摄像头”到”阈值分割”这5个按钮的功能,也就是给每个按钮指定一个”函数”,逻辑代码写在这个函数里面。这种函数就称为事件,Qt中称为槽连接。
点击Designer工具栏的”Edit Signals/Slots”按钮,进入槽函数编辑界面,点击旁边的”Edit Widgets”可以恢复正常视图:
因为我们是用Designer工具设计出的界面,并不是用Python代码敲出来的,所以要想真正运行,需要使用pyuic5将ui文件转成py文件。pyuic5.exe默认在%\Scripts\下,比如我的是在:D:\ProgramData\Anaconda3\Scripts\。 打开cmd命令行,切换到ui文件的保存目录。Windows下有个小技巧,可以在目录的地址栏输入cmd,一步切换到当前目录: 然后执行这条指令: pyuic5 -o mainForm.py using_pyqt_create_ui.ui 如果出现pyuic5不是内部命令的错误,说明pyuic5的路径没有在环境变量里,添加下就好了。执行正常的话,就会生成mainForm.py文件,里面应该包含一个名为”Ui_MainWindow”的类。 编写逻辑代码在同一工作目录下新建一个”mainEntry.py”的文件,存放逻辑代码。代码中的每部分我都写得比较独立,没有封装成函数,便于理解。代码看上去很长,但很简单,可以每个模块单独看。 import sys import cv2 as cv from PyQt5 import QtCore, QtGui, QtWidgets from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.QtWidgets import QFileDialog, QMainWindow from mainForm import Ui_MainWindow class PyQtMainEntry(QMainWindow, Ui_MainWindow): def __init__(self): super().__init__() self.setupUi(self) self.camera = cv.VideoCapture(0) self.is_camera_opened = False # 摄像头有没有打开标记 # 定时器:30ms捕获一帧 self._timer = QtCore.QTimer(self) self._timer.timeout.connect(self._queryFrame) self._timer.setInterval(30) def btnOpenCamera_Clicked(self): ''' 打开和关闭摄像头 ''' self.is_camera_opened = ~self.is_camera_opened if self.is_camera_opened: self.btnOpenCamera.setText("关闭摄像头") self._timer.start() else: self.btnOpenCamera.setText("打开摄像头") self._timer.stop() def btnCapture_Clicked(self): ''' 捕获图片 ''' # 摄像头未打开,不执行任何操作 if not self.is_camera_opened: return self.captured = self.frame # 后面这几行代码几乎都一样,可以尝试封装成一个函数 rows, cols, channels = self.captured.shape bytesPerLine = channels * cols # Qt显示图片时,需要先转换成QImgage类型 QImg = QImage(self.captured.data, cols, rows, bytesPerLine, QImage.Format_RGB888) self.labelCapture.setPixmap(QPixmap.fromImage(QImg).scaled( self.labelCapture.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation)) def btnReadImage_Clicked(self): ''' 从本地读取图片 ''' # 打开文件选取对话框 filename, _ = QFileDialog.getOpenFileName(self, '打开图片') if filename: self.captured = cv.imread(str(filename)) # OpenCV图像以BGR通道存储,显示时需要从BGR转到RGB self.captured = cv.cvtColor(self.captured, cv.COLOR_BGR2RGB) rows, cols, channels = self.captured.shape bytesPerLine = channels * cols QImg = QImage(self.captured.data, cols, rows, bytesPerLine, QImage.Format_RGB888) self.labelCapture.setPixmap(QPixmap.fromImage(QImg).scaled( self.labelCapture.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation)) def btnGray_Clicked(self): ''' 灰度化 ''' # 如果没有捕获图片,则不执行操作 if not hasattr(self, "captured"): return self.cpatured = cv.cvtColor(self.captured, cv.COLOR_RGB2GRAY) rows, columns = self.cpatured.shape bytesPerLine = columns # 灰度图是单通道,所以需要用Format_Indexed8 QImg = QImage(self.cpatured.data, columns, rows, bytesPerLine, QImage.Format_Indexed8) self.labelResult.setPixmap(QPixmap.fromImage(QImg).scaled( self.labelResult.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation)) def btnThreshold_Clicked(self): ''' Otsu自动阈值分割 ''' if not hasattr(self, "captured"): return _, self.cpatured = cv.threshold( self.cpatured, 0, 255, cv.THRESH_BINARY + cv.THRESH_OTSU) rows, columns = self.cpatured.shape bytesPerLine = columns # 阈值分割图也是单通道,也需要用Format_Indexed8 QImg = QImage(self.cpatured.data, columns, rows, bytesPerLine, QImage.Format_Indexed8) self.labelResult.setPixmap(QPixmap.fromImage(QImg).scaled( self.labelResult.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation)) @QtCore.pyqtSlot() def _queryFrame(self): ''' 循环捕获图片 ''' ret, self.frame = self.camera.read() img_rows, img_cols, channels = self.frame.shape bytesPerLine = channels * img_cols cv.cvtColor(self.frame, cv.COLOR_BGR2RGB, self.frame) QImg = QImage(self.frame.data, img_cols, img_rows, bytesPerLine, QImage.Format_RGB888) self.labelCamera.setPixmap(QPixmap.fromImage(QImg).scaled( self.labelCamera.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation)) if __name__ == "__main__": app = QtWidgets.QApplication(sys.argv) window = PyQtMainEntry() window.show() sys.exit(app.exec_()) 程序运行情况 |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |