diff --git a/mainEntry.py b/mainEntry.py index 2409d18..419b0f4 100644 --- a/mainEntry.py +++ b/mainEntry.py @@ -1,7 +1,6 @@ import os import sys import cv2 as cv -import numpy as np from PyQt5 import QtCore, QtGui, QtWidgets from PyQt5.QtCore import * @@ -13,52 +12,70 @@ os.chdir(sys.path[0]) class PyQtMainEntry(QMainWindow, Ui_MainWindow): def __init__(self): - super().__init__() - self.setupUi(self) + super().__init__() # 调用父类的初始化函数 + self.setupUi(self) # 设置用户界面 + + # 初始化摄像头,并尝试打开,默认尝试打开摄像头索引为0 self.camera = cv.VideoCapture(0) - self.is_camera_opened = False + self.is_camera_opened = False # 标记摄像头是否成功打开 + # 创建一个定时器,并设置其触发间隔为10毫秒 self._timer = QtCore.QTimer(self) - self._timer.timeout.connect(self._queryFrame) - self._timer.setInterval(10) + self._timer.timeout.connect(self._queryFrame) # 定时器触发时调用_queryFrame函数 + self._timer.setInterval(10) # 设置定时器触发间隔 - def btnOpenCamera_Clicked(self): + 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)) @@ -93,19 +110,27 @@ class PyQtMainEntry(QMainWindow, Ui_MainWindow): @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 @@ -119,6 +144,17 @@ class PyQtMainEntry(QMainWindow, Ui_MainWindow): 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() diff --git a/surface.py b/surface.py index c5cb3de..2b62230 100644 --- a/surface.py +++ b/surface.py @@ -14,7 +14,7 @@ from PyQt5 import QtCore, QtGui, QtWidgets class Ui_MainWindow(object): def setupUi(self, MainWindow): MainWindow.setObjectName("MainWindow") - MainWindow.resize(832, 441) + MainWindow.resize(664, 436) self.centralwidget = QtWidgets.QWidget(MainWindow) self.centralwidget.setObjectName("centralwidget") self.btnOpenCamera = QtWidgets.QPushButton(self.centralwidget) @@ -33,21 +33,24 @@ class Ui_MainWindow(object): self.btnGray.setGeometry(QtCore.QRect(190, 310, 75, 23)) self.btnGray.setObjectName("btnGray") self.labelCamera = QtWidgets.QLabel(self.centralwidget) - self.labelCamera.setGeometry(QtCore.QRect(0, 40, 150, 150)) + self.labelCamera.setGeometry(QtCore.QRect(20, 40, 150, 150)) self.labelCamera.setFrameShadow(QtWidgets.QFrame.Plain) self.labelCamera.setObjectName("labelCamera") self.labelCapture = QtWidgets.QLabel(self.centralwidget) - self.labelCapture.setGeometry(QtCore.QRect(150, 40, 150, 150)) + self.labelCapture.setGeometry(QtCore.QRect(200, 40, 150, 150)) self.labelCapture.setObjectName("labelCapture") self.labelResult = QtWidgets.QLabel(self.centralwidget) - self.labelResult.setGeometry(QtCore.QRect(310, 40, 150, 150)) + self.labelResult.setGeometry(QtCore.QRect(380, 40, 150, 150)) self.labelResult.setObjectName("labelResult") self.btnDenoising = QtWidgets.QPushButton(self.centralwidget) self.btnDenoising.setGeometry(QtCore.QRect(330, 310, 75, 23)) self.btnDenoising.setObjectName("btnDenoising") + self.btnSaveImage = QtWidgets.QPushButton(self.centralwidget) + self.btnSaveImage.setGeometry(QtCore.QRect(190, 360, 75, 23)) + self.btnSaveImage.setObjectName("btnSaveImage") MainWindow.setCentralWidget(self.centralwidget) self.menubar = QtWidgets.QMenuBar(MainWindow) - self.menubar.setGeometry(QtCore.QRect(0, 0, 832, 22)) + self.menubar.setGeometry(QtCore.QRect(0, 0, 664, 22)) self.menubar.setObjectName("menubar") MainWindow.setMenuBar(self.menubar) self.statusbar = QtWidgets.QStatusBar(MainWindow) @@ -61,6 +64,7 @@ class Ui_MainWindow(object): self.btnThreshold.clicked.connect(MainWindow.btnThreshold_Clicked) # type: ignore self.btnGray.clicked.connect(MainWindow.btnGray_Clicked) # type: ignore self.btnDenoising.clicked.connect(MainWindow.btnDenoising_Clicked) # type: ignore + self.btnSaveImage.clicked.connect(MainWindow.btnSaveImage_Clicked) # type: ignore QtCore.QMetaObject.connectSlotsByName(MainWindow) MainWindow.setTabOrder(self.btnOpenCamera, self.btnCapture) MainWindow.setTabOrder(self.btnCapture, self.btnReadImage) @@ -79,3 +83,4 @@ class Ui_MainWindow(object): self.labelCapture.setText(_translate("MainWindow", "捕获图")) self.labelResult.setText(_translate("MainWindow", "结果图")) self.btnDenoising.setText(_translate("MainWindow", "加噪")) + self.btnSaveImage.setText(_translate("MainWindow", "保存图片"))