1.创建一个 PyQt 应用程序,该应用程序能够:
(1)使用 OpenCV 加载一张图像。
(2)在 PyQt 的窗口中显示这张图像。
(3)提供四个按钮(QPushButton):
一个用于将图像转换为灰度图
一个用于将图像恢复为原始彩色图
一个用于将图像进行翻转
一个用于将图像进行旋转
(4)当用户点击按钮时,相应地更新窗口中显示的图像。
import cv2
import sys
from PyQt6 import uic
from PyQt6.QtCore import Qt
from PyQt6.QtWidgets import QApplication, QMainWindow, QPushButton, QLabel
from PyQt6.QtGui import QImage, QPixmap
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
ui = uic.loadUi("./1.ui", self)
self.pushButton: QPushButton = ui.pushButton
self.pushButton2: QPushButton = ui.pushButton2
self.pushButton3: QPushButton = ui.pushButton3
self.pushButton4: QPushButton = ui.pushButton4
self.label: QLabel = ui.label
self.original_image = cv2.imread("../images/lena.png")
self.current_image = self.original_image
self.load_image()
self.pushButton.clicked.connect(self.convert_to_gray)
self.pushButton2.clicked.connect(self.restore_original)
self.pushButton3.clicked.connect(self.flip_image)
self.pushButton4.clicked.connect(self.rotate_image)
def load_image(self):
# 获取图像的宽度、高度和通道数
image_rgb = cv2.cvtColor(self.current_image, cv2.COLOR_BGR2RGB)
height, width, channels = image_rgb.shape
bytes_per_line = channels * width
# 创建 QImage 对象
qimage = QImage(image_rgb.data, width, height, bytes_per_line, QImage.Format.Format_RGB888)
# 创建 QPixmap 对象,并缩放适应 QLabel
pixmap = QPixmap.fromImage(qimage)
scaled_pixmap = pixmap.scaled(self.label.width(), self.label.height(),
aspectRatioMode=Qt.AspectRatioMode.KeepAspectRatio)
# 将缩放后的 QPixmap 显示到 QLabel 上
self.label.setPixmap(scaled_pixmap)
def convert_to_gray(self):
"""按钮1: 将图像转换为灰度图并显示"""
gray_image = cv2.cvtColor(self.original_image, cv2.COLOR_BGR2GRAY)
# 将灰度图转换为伪RGB格式(3通道)
self.current_image = cv2.cvtColor(gray_image, cv2.COLOR_GRAY2RGB)
self.load_image()
def restore_original(self):
"""按钮2: 恢复为原始彩色图像并显示"""
self.current_image = self.original_image # 恢复为原始彩色图像
self.load_image() # 重新加载并显示
def flip_image(self):
"""按钮3: 翻转图像并显示"""
flipped_image = cv2.flip(self.current_image, 1) # 水平翻转
self.current_image = flipped_image
self.load_image() # 重新加载并显示
def rotate_image(self):
"""按钮4: 顺时针旋转图像90度并显示"""
# 获取图像的中心
center = (self.current_image.shape[1] // 2, self.current_image.shape[0] // 2)
# 创建旋转矩阵,旋转角度 -90(顺时针旋转90度)
rotation_matrix = cv2.getRotationMatrix2D(center, -90, 1.0)
# 旋转图像,输出图像大小为当前图像的宽高
rotated_image = cv2.warpAffine(self.current_image, rotation_matrix,
(self.current_image.shape[1], self.current_image.shape[0]))
# 更新当前图像
self.current_image = rotated_image
# 重新加载并显示图像
self.load_image()
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec())
2. 创建一个 PyQt 应用程序,该应用程序能够:
(1)使用 OpenCV 加载一张彩色图像,并在 PyQt 的窗口中显示它。
(2)提供一个滑动条(QSlider),允许用户调整图像的亮度。
(3)当用户调整滑动条时,实时更新窗口中显示的图像亮度。
(4)添加另一个滑动条(QSlider),允许用户调整图像的对比度。
(5)当用户调整滚动条时,实时更新窗口中显示的图像对比度。
(6)提供一个按钮(QPushButton),允许用户将图像保存为新的文件。
(7)当用户点击保存按钮时,将调整后的图像保存到指定的路径,OpenCV中使用cv2.imwrite()来保存图片。
import cv2
import sys
from PyQt6 import uic
from PyQt6.QtCore import Qt
from PyQt6.QtWidgets import QApplication, QMainWindow, QPushButton, QLabel, QSlider, QFileDialog
from PyQt6.QtGui import QImage, QPixmap
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
ui = uic.loadUi("./2.ui", self)
self.button: QPushButton = ui.pushButton
self.label: QLabel = ui.label
self.horizontalSlider: QSlider = ui.horizontalSlider
self.horizontalSlider2: QSlider = ui.horizontalSlider2
self.original_image = cv2.imread("../images/lena.png")
self.current_image = self.original_image
self.horizontalSlider.valueChanged.connect(self.update_image)
self.horizontalSlider2.valueChanged.connect(self.update_image)
self.button.clicked.connect(self.save_image)
self.load_image()
def load_image(self):
# 获取图像的宽度、高度和通道数
image_rgb = cv2.cvtColor(self.current_image, cv2.COLOR_BGR2RGB)
height, width, channels = image_rgb.shape
bytes_per_line = channels * width
# 创建 QImage 对象
qimage = QImage(image_rgb.data, width, height, bytes_per_line, QImage.Format.Format_RGB888)
# 创建 QPixmap 对象,并缩放适应 QLabel
pixmap = QPixmap.fromImage(qimage)
scaled_pixmap = pixmap.scaled(self.label.width(), self.label.height(),
aspectRatioMode=Qt.AspectRatioMode.KeepAspectRatio)
# 将缩放后的 QPixmap 显示到 QLabel 上
self.label.setPixmap(scaled_pixmap)
def update_image(self):
"""根据当前亮度和对比度调整图像并显示"""
brightness = self.horizontalSlider.value() # 获取亮度值
contrast = self.horizontalSlider2.value() # 获取对比度值
# 调整亮度和对比度
self.current_image = cv2.convertScaleAbs(self.original_image, alpha=contrast / 100.0, beta=brightness)
# 转换为 RGB 格式用于显示
image_rgb = cv2.cvtColor(self.current_image, cv2.COLOR_BGR2RGB)
height, width, channels = image_rgb.shape
bytes_per_line = channels * width
# 创建 QImage 对象
qimage = QImage(image_rgb.data, width, height, bytes_per_line, QImage.Format.Format_RGB888)
# 创建 QPixmap 对象,并缩放适应 QLabel
pixmap = QPixmap.fromImage(qimage)
scaled_pixmap = pixmap.scaled(self.label.width(), self.label.height(),
aspectRatioMode=Qt.AspectRatioMode.KeepAspectRatio)
# 将图像显示到 QLabel 上
self.label.setPixmap(scaled_pixmap)
def save_image(self):
"""保存当前调整后的图像"""
# 弹出文件对话框,选择保存路径
file_path, _ = QFileDialog.getSaveFileName(self, "Save Image", "", "Images (*.png *.jpg *.bmp);;All Files (*)")
if file_path:
# 保存调整后的图像
cv2.imwrite(file_path, self.current_image) # 保存调整后的图像
print(f"Image saved to {file_path}")
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec())
3.创建一个 PyQt 应用程序,该应用程序能够:
(1)使用 OpenCV 加载一张图像。
(2)在 PyQt 的窗口中显示这张图像。
(3)提供一个下拉列表(QComboBox),对图像做(模糊、锐化、边缘检测)处理:
模糊——使用cv2.GaussianBlur()实现
锐化——使用cv2.Laplacian()、cv2.Sobel()实现
边缘检测——使用cv2.Canny()实现
(4)当用户点击下拉列表选项时,相应地更新窗口中显示的图像。
(5)提供一个按钮,当用户点击按钮时,能保存调整后的图像。
import cv2
import sys
from PyQt6 import uic
from PyQt6.QtCore import Qt
from PyQt6.QtWidgets import QApplication, QMainWindow, QPushButton, QLabel, QFileDialog, QComboBox
from PyQt6.QtGui import QImage, QPixmap
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
ui = uic.loadUi("./3.ui", self)
# 获取控件对象
self.button: QPushButton = ui.pushButton
self.label: QLabel = ui.label
self.comboBox: QComboBox = ui.comboBox
# 加载图像
self.original_image = cv2.imread("../images/lena.png")
self.current_image = self.original_image.copy()
# 设置下拉列表的选项
self.comboBox.addItem("选择处理方式")
self.comboBox.addItem("模糊")
self.comboBox.addItem("锐化 (Laplacian)")
self.comboBox.addItem("锐化 (Sobel)")
self.comboBox.addItem("边缘检测")
# 连接下拉列表的选择变化信号
self.comboBox.activated.connect(self.process_image)
# 连接保存按钮点击事件
self.button.clicked.connect(self.save_image)
# 初始化图像显示
self.load_image()
def load_image(self):
"""将图像加载到 QLabel 中显示"""
# 将图像从 BGR 转换为 RGB 格式
image_rgb = cv2.cvtColor(self.current_image, cv2.COLOR_BGR2RGB)
height, width, channels = image_rgb.shape
bytes_per_line = channels * width
# 创建 QImage 对象
qimage = QImage(image_rgb.data, width, height, bytes_per_line, QImage.Format.Format_RGB888)
# 创建 QPixmap 对象,并缩放适应 QLabel
pixmap = QPixmap.fromImage(qimage)
scaled_pixmap = pixmap.scaled(self.label.width(), self.label.height(),
aspectRatioMode=Qt.AspectRatioMode.KeepAspectRatio)
# 将缩放后的 QPixmap 显示到 QLabel 上
self.label.setPixmap(scaled_pixmap)
def process_image(self):
"""根据下拉列表选择的项处理图像"""
selected_option = self.comboBox.currentText()
if selected_option == "模糊":
# 使用高斯模糊
self.current_image = cv2.GaussianBlur(self.original_image, (15, 15), 0)
elif selected_option == "锐化 (Laplacian)":
# 使用拉普拉斯算子进行锐化
laplacian = cv2.Laplacian(self.original_image, cv2.CV_64F)
# 将拉普拉斯算子结果转换为 uint8 类型
laplacian = cv2.convertScaleAbs(laplacian)
# 加权合成原图和拉普拉斯算子的结果,进行锐化
self.current_image = cv2.addWeighted(self.original_image, 1.5, laplacian, -0.5, 0)
elif selected_option == "锐化 (Sobel)":
# 使用 Sobel 算子进行锐化
sobel_x = cv2.Sobel(self.original_image, cv2.CV_64F, 1, 0, ksize=3)
sobel_y = cv2.Sobel(self.original_image, cv2.CV_64F, 0, 1, ksize=3)
sobel_edge = cv2.magnitude(sobel_x, sobel_y) # 计算梯度的幅值
self.current_image = cv2.addWeighted(self.original_image, 1.5, sobel_edge.astype('uint8'), 0.5, 0)
elif selected_option == "边缘检测":
# 使用 Canny 边缘检测
self.current_image = cv2.Canny(self.original_image, 100, 200)
# 每次选择后更新图像显示
self.load_image()
def save_image(self):
"""保存当前调整后的图像"""
# 弹出文件对话框,选择保存路径
file_path, _ = QFileDialog.getSaveFileName(self, "Save Image", "", "Images (*.png *.jpg *.bmp);;All Files (*)")
if file_path:
# 保存调整后的图像
cv2.imwrite(file_path, self.current_image)
print(f"Image saved to {file_path}")
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec())
4.请编写一段Python代码,实现以下功能:
(1)读取一张二维码图片
(2)进行二值化处理和形态学操作,获取二维码轮廓
(3)通过轮廓外接特征检测或者多边形逼近等获取 二维码的四个点
(4)进行透视变换,矫正二维码图像
import cv2
import numpy as np
# 1. 读取二维码图像
image = cv2.imread('./er2.png') # 请根据需要修改图像路径
# 2. 将图像转换为灰度图
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 3. 二值化处理
_, binary = cv2.threshold(gray, 100, 255, cv2.THRESH_BINARY_INV)
# 4. 形态学操作 - 腐蚀和膨胀,增强轮廓
kernel1 = np.ones((3, 3), np.uint8)
kernel2 = np.ones((13, 13), np.uint8)
eroded = cv2.erode(binary, kernel1, iterations=1)
dilated = cv2.dilate(eroded, kernel2, iterations=2)
eroded2 = cv2.erode(dilated, kernel2, iterations=1)
# 5. 查找轮廓
contours, _ = cv2.findContours(eroded2, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# 6. 遍历轮廓,寻找最大的四边形轮廓
for contour in contours:
# 计算轮廓的多边形逼近
epsilon = 0.02 * cv2.arcLength(contour, True)
approx = cv2.approxPolyDP(contour, epsilon, True)
# 如果多边形有4个点,说明是二维码
if len(approx) == 4:
# 获取四个顶点
points = approx.reshape(4, 2) # 修改:将points调整为(4, 2)的形状
print(f"QR code corners detected: {points}")
# 画出轮廓和四个角点
cv2.drawContours(image, [approx], -1, (0, 255, 0), 2)
for point in points:
cv2.circle(image, tuple(point), 10, (0, 0, 255), -1)
cv2.imshow("QR Code", image)
# 进行透视变换
# 对四个点进行排序:左上、右上、右下、左下
rect = np.zeros((4, 2), dtype="float32")
# 按照总的顺序排布
s = points.sum(axis=1)
rect[0] = points[np.argmin(s)] # 左上
rect[2] = points[np.argmax(s)] # 右下
diff = np.diff(points, axis=1)
rect[1] = points[np.argmin(diff)] # 右上
rect[3] = points[np.argmax(diff)] # 左下
# 获取二维码图像的宽度和高度
(tl, tr, br, bl) = rect
width = max(int(np.linalg.norm(br - bl)), int(np.linalg.norm(tr - tl)))
height = max(int(np.linalg.norm(tr - br)), int(np.linalg.norm(tl - bl)))
# 目标点 (按顺序排列)
dst = np.array([
[0, 0],
[width, 0],
[width, height],
[0, height]
], dtype="float32")
# 计算透视变换矩阵
M = cv2.getPerspectiveTransform(rect, dst)
# 进行透视变换
warped = cv2.warpPerspective(image, M, (width, height))
# 显示透视变换后的二维码
cv2.imshow("Warped QR Code", warped)
cv2.waitKey(0)
cv2.destroyAllWindows()
运行结果:
5. 请编写一段Python代码,实现以下功能:
(1)读取一张彩色图像
(2)制作要提取颜色的掩膜
(3)输出抠图后的前景图 和 背景图
import cv2
import numpy as np
# 1. 读取彩色图像
image = cv2.imread('./hua2.png') # 修改为你的图像路径
# 2. 将图像从 BGR 转换到 HSV
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
# 3. 黄色的HSV范围
lower_y = np.array([11, 43, 46])
upper_y = np.array([34, 255, 255])
# 4. 创建两个掩膜
mask = cv2.inRange(hsv, lower_y, upper_y)
# 5. 输出前景图和背景图
# 前景图:通过掩膜提取前景
foreground = cv2.bitwise_and(image, image, mask=mask)
# 背景图:反掩膜提取背景
mask_inv = cv2.bitwise_not(mask)
background = cv2.bitwise_and(image, image, mask=mask_inv)
# 6. 显示结果
cv2.imshow("Original Image", image)
cv2.imshow("Foreground", foreground)
cv2.imshow("Background", background)
cv2.waitKey(0)
cv2.destroyAllWindows()
运行结果