open_cv小练习
一.设计思路
1.思路分析与设计
本段代码是一个使用 PyQt6 和 OpenCV 创建的图像处理应用程序。其主要功能是通过一个图形界面让用户对图片进行基本的图像处理操作,如灰度化、翻转、旋转、亮度与对比度调整,以及一些滤镜效果(模糊、锐化、边缘检测等)。应用程序的核心思想是将图像通过不同的算法进行处理,并通过一个图形用户界面与用户进行交互。
2.主要设计思路
界面设计:
通过 PyQt6 提供的 QWidget 基础类构建一个窗口界面。
在界面中使用了 QLabel 显示图像,使用 QPushButton 实现用户操作按钮,使用 QSlider 控制图像亮度和对比度,使用 QComboBox 提供滤镜选择。
图像加载与转换:
使用 OpenCV 的 cv2.imread() 函数加载图像。
将 OpenCV 中使用的 BGR 图像格式转换为适合 PyQt6 显示的 RGB 格式,并将其转换为 QImage,然后再转换为 QPixmap 显示在 QLabel 上。
事件与信号槽机制:
通过 PyQt6 提供的信号-槽机制将 GUI 元素(如按钮、滑块、下拉框)与对应的处理函数进行关联。
点击按钮或滑动滑块时,程序会相应地调用相应的图像处理函数,处理后的图像通过更新 QLabel 的显示内容反馈给用户。
图像处理:
灰度化:将图片转换为灰度图像,通过 cv2.cvtColor() 函数实现。
翻转:通过 cv2.flip() 函数实现水平翻转。
旋转:通过 cv2.getRotationMatrix2D() 和 cv2.warpAffine() 函数实现图片的旋转。
亮度与对比度调整:通过滑块获取当前值,对图像进行线性亮度和对比度调整。
滤镜处理:通过下拉框选择不同的滤镜效果,如模糊、锐化、边缘检测等,利用 OpenCV 中的相应函数(如 cv2.blur()、cv2.GaussianBlur()、cv2.Canny())处理图像。
保存图片:
用户可以通过按钮将处理后的图像保存到本地。
二.设计到的函数方法
1. Qimg(self, img)
功能:将 OpenCV 图像格式(BGR)转换为 PyQt6 可以显示的格式(RGB 和 QImage)。
实现:
使用 cv2.cvtColor() 将图像从 BGR 转换为 RGB 格式。
使用 QImage 类构造图像对象,准备好用于显示。
2. gray_image(self)
功能:将图像转换为灰度图像并更新显示。
实现:
使用 cv2.cvtColor() 将图像转换为灰度图。
更新 QLabel 中显示的图像。
3. rec(self)
功能:恢复原图,重新加载图片。
实现:
使用 cv2.imread() 重新加载原始图片并更新显示。
4. flip(self)
功能:翻转图像(水平翻转)。
实现:
使用 cv2.flip() 执行水平翻转。
更新显示的图像。
5. warp(self)
功能:旋转图像(90度旋转)。
实现:
使用 cv2.getRotationMatrix2D() 和 cv2.warpAffine() 进行旋转。
更新显示的图像。
6. bright(self)
功能:调整图像的亮度和对比度。
实现:
获取滑块的值,计算出相应的亮度和对比度调整系数。
使用这些系数调整图像的像素值,并更新显示。
7. save(self)
功能:保存当前图像到本地文件。
实现:
使用 cv2.imwrite() 保存图像。
8. dispose(self)
功能:根据选择的滤镜效果(模糊、锐化、边缘检测)处理图像。
实现:
使用下拉框选择不同的滤镜效果,并根据选择的内容应用相应的图像处理方法。
三.代码
import os
import sys
import cv2
import numpy as np
from PyQt6.QtGui import QPixmap
from PyQt6.QtWidgets import QFileDialog, QWidget, QApplication
from PyQt6 import uic
class MyWidget(QWidget):
def __init__(self):
super().__init__()
self.ui = uic.loadUi("./form.ui", self)
self.img_path = ''
self.path = ''
self.list = ['模糊', '锐化', '边缘检测']
self.ui.btn1.clicked.connect(self.open_image)
self.ui.btn2.clicked.connect(self.flip_image)
self.ui.btn3.clicked.connect(self.gray_image)
self.ui.btn4.clicked.connect(self.save_image)
self.ui.btn5.clicked.connect(self.revolve_image)
self.ui.btn6.clicked.connect(self.recover_image)
self.ui.btn7.clicked.connect(self.close)
self.ui.slider1.valueChanged.connect(self.slider)
self.ui.slider2.valueChanged.connect(self.slider)
self.ui.comboBox.activated.connect(self.getComboBox)
self.ui.comboBox.addItems(self.list)
def open_image(self):
file_path, _ = QFileDialog.getOpenFileName(self, "读取图片", "./", "Image Files (*.png *.jpg *.bmp)")
if file_path:
self.img_path = file_path
self.ui.label.setPixmap(QPixmap(file_path))
self.ui.label.setScaledContents(True)
self.path = self.img_path
def save_image(self):
file_path, _ = QFileDialog.getSaveFileName(self, "保存图片", "./", "Image Files (*.png *.jpg *.bmp)")
if file_path:
self.ui.label.pixmap().save(file_path)
def gray_image(self):
img = cv2.imread(self.img_path)
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
cv2.imwrite("./gray.png", img_gray)
self.ui.label.setPixmap(QPixmap("./gray.png"))
self.ui.label.setScaledContents(True)
self.img_path = "./gray.png"
def recover_image(self):
self.ui.label.setPixmap(QPixmap("./recover.png"))
self.ui.label.setScaledContents(True)
self.img_path = "./recover.png"
def revolve_image(self):
img1 = cv2.imread(self.img_path)
img2 = cv2.imread(self.path)
M1 = cv2.getRotationMatrix2D((img1.shape[1]/2, img1.shape[0]/2), 90, -1)
M2 = cv2.getRotationMatrix2D((img2.shape[1]/2, img2.shape[0]/2), 90, -1)
img_rotate1 = cv2.warpAffine(img1, M1, (img1.shape[1], img1.shape[0]))
img_rotate2 = cv2.warpAffine(img2, M2, (img2.shape[1], img2.shape[0]))
cv2.imwrite("./rotate.png", img_rotate1)
cv2.imwrite("./recover.png", img_rotate2)
self.ui.label.setPixmap(QPixmap("./rotate.png"))
self.img_path = "./rotate.png"
self.path = "./recover.png"
def flip_image(self):
img1 = cv2.imread(self.img_path)
img2 = cv2.imread(self.path)
img_flip1 = cv2.flip(img1, -1)
img_flip2 = cv2.flip(img2, -1)
cv2.imwrite("./flip.png", img_flip1)
cv2.imwrite("./recover.png", img_flip2)
self.ui.label.setPixmap(QPixmap("./flip.png"))
self.img_path = "./flip.png"
self.path = "./recover.png"
def close(self):
if os.path.exists("./flip.png"):
os.remove("./flip.png")
elif os.path.exists("./gray.png"):
os.remove("./gray.png")
elif os.path.exists("./rotate.png"):
os.remove("./rotate.png")
elif os.path.exists("./recover.png"):
os.remove("./recover.png")
elif os.path.exists("./slider.png"):
os.remove("./slider.png")
elif os.path.exists("./blur.png"):
os.remove("./blur.png")
elif os.path.exists("./canny.png"):
os.remove("./canny.png")
elif os.path.exists("./laplace.png"):
os.remove("./laplace.png")
def slider(self):
img = cv2.imread(self.path)
img_copy = img.copy()
slider1 = self.ui.slider1.value()
slider2 = self.ui.slider2.value()
img_copy = (slider2/100.0+1) * img_copy + slider1
img_copy = np.clip(img_copy, 0, 255)
img_copy = np.uint8(img_copy)
cv2.imwrite("./slider.png", img_copy)
self.ui.label.setPixmap(QPixmap("./slider.png"))
self.img_path = "./slider.png"
def blur_image(self):
img1 = cv2.imread(self.img_path)
img2 = cv2.imread(self.path)
img_blur = cv2.GaussianBlur(img1, (5, 5), 0)
cv2.imwrite("./blur.png", img_blur)
cv2.imwrite("./recover.png", img2)
self.ui.label.setPixmap(QPixmap("./blur.png"))
self.img_path = "./blur.png"
self.path = "./recover.png"
def laplace_image(self):
img1 = cv2.imread(self.img_path)
img2 = cv2.imread(self.path)
img_laplace = cv2.Laplacian(img1, cv2.CV_64F)
img_laplace = cv2.convertScaleAbs(img_laplace)
cv2.imwrite("./laplace.png", img_laplace)
cv2.imwrite("./recover.png", img2)
self.ui.label.setPixmap(QPixmap("./laplace.png"))
self.img_path = "./laplace.png"
self.path = "./recover.png"
def canny_image(self):
img1 = cv2.imread(self.img_path)
img2 = cv2.imread(self.path)
copy = img1.copy()
img_canny = cv2.Canny(copy, 100, 200)
contours,_ = cv2.findContours(img_canny, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
copy = cv2.drawContours(copy, contours, -1, (0, 255, 0),3)
cv2.imwrite("./canny.png", copy)
cv2.imwrite("./recover.png", img2)
self.ui.label.setPixmap(QPixmap("./canny.png"))
self.img_path = "./canny.png"
self.path = "./recover.png"
def getComboBox(self):
if self.ui.comboBox.currentText() == "模糊":
self.blur_image()
elif self.ui.comboBox.currentText() == "锐化":
self.laplace_image()
elif self.ui.comboBox.currentText() == "边缘检测":
self.canny_image()
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MyWidget()
window.show()
sys.exit(app.exec())
四.结果
读取图片
图片翻折
灰度化
图片旋转
复原
模糊
锐化
边缘检测
亮度和对比度