1、题目一
1.使用 OpenCV 加载一张图像。
2.在 PyQt 的窗口中显示这张图像。
3.提供四个按钮(QPushButton):
一个用于将图像转换为灰度图
一个用于将图像恢复为原始彩色图
一个用于将图像进行翻转
一个用于将图像进行旋转
4.当用户点击按钮时,相应地更新窗口中显示的图像。
整体结构
- 加载 UI 文件:使用 uic.loadUi('./demo1.ui', self) 加载名为 demo1.ui 的 UI 文件,该文件定义了图形界面的布局和组件。
- 获取 UI 组件:通过 UI 文件中的对象名获取各个组件,包括一个用于显示图像的标签 self.lab 和四个用于触发不同操作的按钮 self.btn1、self.btn2、self.btn3、self.btn4。
- 加载图像:使用 cv2.imread('../1iamge/a.jpg') 从指定路径加载一张彩色图像,并将其存储在 self.img 中。
- 连接信号与槽 :将每个按钮的 clicked 信号连接到相应的槽函数。
- self.btn1.clicked.connect(self.gray):当 btn1 被点击时,调用 gray 方法将图像转换为灰度图。
- self.btn2.clicked.connect(self.show_img):当 btn2 被点击时,调用 show_img 方法显示当前图像。
- self.btn3.clicked.connect(self.flip_image):当 btn3 被点击时,调用 flip_image 方法水平翻转图像。
- self.btn4.clicked.connect(self.rotate_image):当 btn4 被点击时,调用 rotate_image 方法将图像旋转 90 度。
灰度转换方法 gray
- 转换为灰度图:使用 cv2.cvtColor(self.img, cv2.COLOR_BGR2GRAY) 将彩色图像转换为灰度图。
- 获取灰度图尺寸和字节数:获取灰度图的高度和宽度,计算每行的字节数。
- 创建并设置QPixmap:从灰度图的 QImage 创建 QPixmap,并将其设置到标签 self.lab 中显示,同时设置标签的内容自适应大小。
图像翻转:flip
- 水平翻转图像:使用 cv2.flip(self.img, 1) 对图像进行水平翻转,其中参数 1 表示水平方向翻转。
- 显示翻转后的图像:调用 show_img 方法显示翻转后的图像。
图像旋转:(getRotationMatrix2D,warpAffine)
- 计算旋转矩阵:使用 cv2.getRotationMatrix2D 计算旋转矩阵,以图像中心为旋转点,旋转角度为 90 度,缩放因子为 1。
- 应用旋转矩阵:使用 cv2.warpAffine 对图像应用旋转矩阵,实现图像旋转。
- 显示旋转后的图像:调用 show_img 方法显示旋转后的图像。
完整代码
python
from PyQt6.QtGui import QPixmap, QImage
from PyQt6.QtWidgets import QWidget, QApplication, QLabel, QPushButton
from PyQt6 import uic
import sys
import cv2
class MyWiget(QWidget):
def __init__(self):
super().__init__()
ui = uic.loadUi('./demo1.ui',self)
self.lab:QLabel = ui.label
self.btn1:QPushButton = ui.btn1
self.btn2:QPushButton = ui.btn2
self.btn3:QPushButton = ui.btn3
self.btn4:QPushButton = ui.btn4
self.img = cv2.imread('../1iamge/a.jpg')
self.btn1.clicked.connect(self.gray)
self.btn2.clicked.connect(self.show_img)
self.btn3.clicked.connect(self.flip_image)
self.btn4.clicked.connect(self.rotate_image)
def show_img(self):
# 将cv2读取的图片放入label中
height, width, channel = self.img.shape
bytes_per_line = 3 * width
# 将BGR格式的cv2图像转换为QImage,注意格式指定以及颜色通道转换(Qt用RGB顺序)
qimg = QImage(self.img.data, width, height, bytes_per_line, QImage.Format.Format_RGB888).rgbSwapped()
pixmap = QPixmap.fromImage(qimg)
self.lab.setPixmap(pixmap)
self.lab.setScaledContents(True)
def gray(self):
self.img_gray = cv2.cvtColor(self.img, cv2.COLOR_BGR2GRAY)
height, width = self.img_gray.shape
bytes_per_line = width
qimg = QImage(self.img_gray.data, width, height, bytes_per_line, QImage.Format.Format_Grayscale8)
pixmap = QPixmap.fromImage(qimg)
self.lab.setPixmap(pixmap)
self.lab.setScaledContents(True)
def flip_image(self):
self.img = cv2.flip(self.img, 1)
self.show_img()
def rotate_image(self):
rows, cols = self.img.shape[:2]
M = cv2.getRotationMatrix2D((cols / 2, rows / 2), 90, 1)
self.img = cv2.warpAffine(self.img, M, (cols, rows))
self.show_img()
if __name__ == '__main__':
app = QApplication(sys.argv)
mywidget = MyWiget()
mywidget.show()
mywidget.show_img()
sys.exit(app.exec())
结果:
2、题目二
1.使用 OpenCV 加载一张彩色图像,并在 PyQt 的窗口中显示它。 2.提供一个滑动条(QSlider),允许用户调整图像的亮度。 3.当用户调整滑动条时,实时更新窗口中显示的图像亮度。 4.添加另一个滑动条(QSlider),允许用户调整图像的对比度。 5.当用户调整滚动条时,实时更新窗口中显示的图像对比度。 6.提供一个按钮(QPushButton),允许用户将图像保存为新的文件。 7.当用户点击保存按钮时,将调整后的图像保存到指定的路径,OpenCV中使用cv2.imwrite()来保存图片。
图像显示方法 show_img
- 获取图像尺寸和字节数 :获取传入图像的高度、宽度和通道数,计算每行的字节数。
- 转换图像格式 :将 OpenCV 的 BGR 格式图像转换为 QImage 格式,并将颜色通道从 BGR 转换为 RGB。
- 创建并设置 QPixmap :从 QImage 创建 QPixmap,并将其设置到标签 self.lab 中显示,同时设置标签的内容自适应大小。
亮度调整方法 update_brightness
- 复制图像 :对原始图像进行复制,得到 self.img_copy1,以避免直接修改原始图像。
- 调整亮度 :使用 cv2.convertScaleAbs 函数,通过设置 alpha=1 和 beta=value(value 为滑动条的值)来调整图像亮度。
- 显示调整后的图像 :调用 self.show_img(self.img_copy1) 显示调整亮度后的图像。
对比度调整方法 update_contrast
- 复制图像 :对原始图像进行复制,得到 self.img_copy2,以避免直接修改原始图像。
- 计算对比度因子 :根据滑动条的值 value 计算对比度因子 alpha = 1 + value / 100.0。
- 调整对比度 :使用 cv2.convertScaleAbs 函数,通过设置 alpha 和 beta=0 来调整图像对比度。
- 显示调整后的图像 :调用 self.show_img(self.img_copy2) 显示调整对比度后的图像。
图像保存方法 save_image
- 获取保存路径 :使用 QFileDialog.getSaveFileName 弹出文件保存对话框,让用户选择保存路径和文件名。
- 保存图像 :如果用户选择了保存路径(file_path 不为空),则使用 cv2.imwrite 将当前显示的图像(即 self.img,但实际应该是调整后的图像,这里代码存在问题)保存到指定路径。
完整代码
python
from PyQt6.QtGui import QPixmap, QImage
from PyQt6.QtWidgets import QWidget, QApplication, QLabel, QPushButton, QSlider, QVBoxLayout, QFileDialog
from PyQt6 import uic
import numpy as np
import sys
import cv2
class MyWidget(QWidget):
def __init__(self):
super().__init__()
ui = uic.loadUi('./demo2.ui', self)
self.lab: QLabel = ui.label
self.btn: QPushButton = ui.btn
self.sld1: QSlider = ui.slider1
self.sld2: QSlider = ui.slider2
# 加载图像
self.img = cv2.imread('../1iamge/011.jpg')
if self.img is None:
raise FileNotFoundError(f"无法找到图像文件:../1iamge/a.jpg")
self.show_img(self.img)
# 设置滑动条的范围
self.sld1.setMinimum(-100)
self.sld1.setMaximum(100)
self.sld2.setMinimum(-100)
self.sld2.setMaximum(100)
# 连接信号和槽
self.sld1.valueChanged.connect(self.update_brightness)
self.sld2.valueChanged.connect(self.update_contrast)
self.btn.clicked.connect(self.save_image)
def show_img(self,img):
height, width, channel = img.shape
bytes_per_line = 3 * width
# 将BGR格式的cv2图像转换为QImage,注意格式指定以及颜色通道转换(Qt用RGB顺序)
qimg = QImage(img.data, width, height, bytes_per_line, QImage.Format.Format_RGB888).rgbSwapped()
pixmap = QPixmap.fromImage(qimg)
self.lab.setPixmap(pixmap)
self.lab.setScaledContents(True)
def update_brightness(self, value):
# 调整亮度
self.img_copy1 = self.img.copy()
self.img_copy1 = cv2.convertScaleAbs(self.img, alpha=1, beta=value)
self.show_img(self.img_copy1)
def update_contrast(self, value):
# 调整对比度
self.img_copy2 = self.img.copy()
alpha = 1 + value / 100.0
self.img_copy2 = cv2.convertScaleAbs(self.img, alpha=alpha, beta=0)
self.show_img(self.img_copy2)
def save_image(self):
# 保存图像
file_path, _ = QFileDialog.getSaveFileName(self, "保存图片", "", "Images (*.png *.jpg *.bmp)")
if file_path:
cv2.imwrite(file_path, self.img)
if __name__ == '__main__':
app = QApplication(sys.argv)
mywidget = MyWidget()
mywidget.show()
sys.exit(app.exec())
结果:
3、题目三
1、导入必要的模块。
2、定义一个MyWidget类,继承自QWidget,用于创建应用程序的主窗口。
3、在MyWidget类的构造函数中,加载UI界面文件,并初始化界面组件。
4、定义了几个方法来处理图像,包括显示原图、模糊处理、锐化处理和边缘检测。
5、在getComboBox方法中,根据下拉列表的选择调用相应的图像处理方法。
6、在主程序部分,创建应用程序实例,显示窗口,并进入事件循环。
1、初始化 UI 组件和变量:
python
# 将ui上的组件加载到程序中来
self.comboBox: QComboBox = ui.comboBox
self.label: QLabel = ui.label
# 读取图片
self.img = cv2.imread('../1iamge/011.jpg')
# 添加一个下拉列表项
self.comboBox.addItem("原图")
# 将列表设置到下拉列表项中
list1 = ["模糊", "锐化", "边缘检测"]
self.comboBox.addItems(list1)
# 连接信号和槽
self.comboBox.activated.connect(self.getComboBox)
获取 UI 文件中的QComboBox和QLabel组件,读取指定路径的图片,向下拉列表中添加选项,并将下拉列表的activated信号连接到getComboBox槽函数。
2、图像处理和显示相关方法:
change_img
方法:
python
def change_img(self,img):
height, width, channel = img.shape
bytes_per_line = 3 * width
# 将BGR格式的cv2图像转换为QImage,注意格式指定以及颜色通道转换(Qt用RGB顺序)
qimg = QImage(img.data, width, height, bytes_per_line, QImage.Format.Format_RGB888).rgbSwapped()
pixmap = QPixmap.fromImage(qimg)
self.label.setPixmap(pixmap)
self.label.setScaledContents(True)
3、将 OpenCV 的 BGR 格式图像转换为适合在 Qt 中显示的QPixmap
格式,并设置到QLabel
上进行显示。
show_img
方法:
python
def show_img(self):
self.change_img(self.img)
4、显示原始图像。
Blur_img
方法:
python
def Blur_img(self):
self.img_blur = cv2.GaussianBlur(self.img, (5, 5), 150)
self.change_img(self.img_blur)
5、使用高斯模糊对图像进行模糊处理,并显示处理后的图像。
Sharpen_img
方法:
python
def Sharpen_img(self):
laplacian = cv2.Laplacian(self.img, cv2.CV_64F)
sobelx = cv2.Sobel(self.img, cv2.CV_64F, 1, 0, ksize=5)
sobely = cv2.Sobel(self.img, cv2.CV_64F, 0, 1, ksize=5)
self.img_copy = self.img + cv2.convertScaleAbs(laplacian) + cv2.convertScaleAbs(sobelx) + cv2.convertScaleAbs(sobely)
self.change_img(self.img_copy)
6、 使用拉普拉斯算子和索贝尔算子对图像进行锐化处理,并显示处理后的图像。
- Edge_detection方法:
python
def Edge_detection(self):
gray_image = cv2.cvtColor(self.img, cv2.COLOR_BGR2GRAY)
self.canny = cv2.Canny(gray_image, 100, 200)
# 将单通道边缘图像转换为三通道以显示
self.canny = cv2.cvtColor(self.canny, cv2.COLOR_GRAY2BGR)
self.change_img(self.canny)
将图像转换为灰度图,使用 Canny 边缘检测算法检测边缘,将单通道边缘图像转换为三通道图像后显示。
7、获取下拉列表选择并处理:
python
def getComboBox(self):
index = self.comboBox.currentIndex()
if index == 1:
self.Blur_img()
elif index == 2:
self.Sharpen_img()
elif index == 3:
self.Edge_detection()
elif index == 0:
self.show_img()
完整代码
python
import sys
import cv2
from PyQt6.QtGui import QPixmap, QImage, QIcon
from PyQt6.QtWidgets import QWidget, QComboBox, QApplication, QLabel
from PyQt6 import uic
class MyWidget(QWidget):
def __init__(self):
super().__init__()
# 将ui界面加载到程序中来
ui = uic.loadUi("./demo3.ui", self)
# 将ui上的组件加载到程序中来
self.comboBox: QComboBox = ui.comboBox
self.label: QLabel = ui.label
# 读取图片
self.img = cv2.imread('../1iamge/011.jpg')
# 添加一个下拉列表项
self.comboBox.addItem("原图")
# 将列表设置到下拉列表项中
list1 = ["模糊", "锐化", "边缘检测"]
self.comboBox.addItems(list1)
# 连接信号和槽
self.comboBox.activated.connect(self.getComboBox)
def change_img(self,img):
height, width, channel = img.shape
bytes_per_line = 3 * width
# 将BGR格式的cv2图像转换为QImage,注意格式指定以及颜色通道转换(Qt用RGB顺序)
qimg = QImage(img.data, width, height, bytes_per_line, QImage.Format.Format_RGB888).rgbSwapped()
pixmap = QPixmap.fromImage(qimg)
self.label.setPixmap(pixmap)
self.label.setScaledContents(True)
# 展示图片
def show_img(self):
self.change_img(self.img)
def Blur_img(self):
self.img_blur = cv2.GaussianBlur(self.img, (5, 5), 150)
self.change_img(self.img_blur)
def Sharpen_img(self):
laplacian = cv2.Laplacian(self.img, cv2.CV_64F)
sobelx = cv2.Sobel(self.img, cv2.CV_64F, 1, 0, ksize=5)
sobely = cv2.Sobel(self.img, cv2.CV_64F, 0, 1, ksize=5)
self.img_copy = self.img + cv2.convertScaleAbs(laplacian) + cv2.convertScaleAbs(sobelx) + cv2.convertScaleAbs(sobely)
self.change_img(self.img_copy)
def Edge_detection(self):
gray_image = cv2.cvtColor(self.img, cv2.COLOR_BGR2GRAY)
self.canny = cv2.Canny(gray_image, 100, 200)
# 将单通道边缘图像转换为三通道以显示
self.canny = cv2.cvtColor(self.canny, cv2.COLOR_GRAY2BGR)
self.change_img(self.canny)
# comboBox值的获取等
def getComboBox(self):
index = self.comboBox.currentIndex()
if index == 1:
self.Blur_img()
elif index == 2:
self.Sharpen_img()
elif index == 3:
self.Edge_detection()
elif index == 0:
self.show_img()
# 测试
if __name__ == "__main__":
app = QApplication(sys.argv)
my = MyWidget()
my.show()
my.show_img()
sys.exit(app.exec())
结果: