import os 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 surface import (Ui_MainWindow) os.chdir(sys.path[0]) class PyQtMainEntry(QMainWindow, Ui_MainWindow): def __init__(self): super().__init__() # 调用父类的初始化函数 self.setupUi(self) # 设置用户界面 # 初始化摄像头,并尝试打开,默认尝试打开摄像头索引为0 self.camera = cv.VideoCapture(0) self.is_camera_opened = False # 标记摄像头是否成功打开 # 创建一个定时器,并设置其触发间隔为10毫秒 self._timer = QtCore.QTimer(self) self._timer.timeout.connect(self._queryFrame) # 定时器触发时调用_queryFrame函数 self._timer.setInterval(10) # 设置定时器触发间隔 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 # 使用捕获的图像数据创建QImage对象 QImg = QImage(self.captured.data, cols, rows, bytesPerLine, QImage.Format_RGB888) # 将QImage对象转换为QPixmap,并按比例缩放以适应标签的大小,然后设置到标签上 self.labelCapture.setPixmap(QPixmap.fromImage(QImg).scaled( self.labelCapture.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation)) def btnReadImage_Clicked(self): # 使用QFileDialog获取选择的图像文件名 # ,_是占位符用来忽略返回值比如这里面会返回文件名和文件类型,使用占位符可以忽略文件类型 filename, _ = QFileDialog.getOpenFileName(self, '打开图片') if filename: # 通过文件名读取图像,并转换为RGB格式 self.captured = cv.imread(str(filename)) self.captured = cv.cvtColor(self.captured, cv.COLOR_BGR2RGB) # 获取图像的尺寸信息,用于创建QImage rows, cols, channels = self.captured.shape bytesPerLine = channels * cols # 将OpenCV图像转换为QImage格式 QImg = QImage(self.captured.data, cols, rows, bytesPerLine, QImage.Format_RGB888) # 将QImage设置为标签的图片,并保持原始比例进行缩放 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 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): 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 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 # 将图像从BGR转换为RGB格式 cv.cvtColor(self.frame, cv.COLOR_BGR2RGB, self.frame) # 创建QImage对象 QImg = QImage(self.frame.data, img_cols, img_rows, bytesPerLine, QImage.Format_RGB888) # 将QImage设置为标签的图片,并保持宽高比 self.labelCamera.setPixmap(QPixmap.fromImage(QImg).scaled( self.labelCamera.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation)) def btnDenoising_Clicked(self): if not hasattr(self, "captured"): return self.cpatured = cv.fastNlMeansDenoising(self.cpatured, None, 10, 7, 21) rows, columns = self.cpatured.shape bytesPerLine = columns 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 btnSaveImage_Clicked(self): if not hasattr(self, "captured"): # 检查是否已捕获图像 return filename, _ = QFileDialog.getSaveFileName(self, '保存图片') # 弹出保存文件对话框 if filename: # 如果用户选择了保存路径 cv.imwrite(str(filename), self.captured) # 将捕获的图像保存到选择的路径 if __name__ == "__main__": app = QtWidgets.QApplication(sys.argv) window = PyQtMainEntry() window.show() sys.exit(app.exec_())