PyQt6+OpenCV 项目练习

1、题目一

1.使用 OpenCV 加载一张图像。

2.在 PyQt 的窗口中显示这张图像。

3.提供四个按钮(QPushButton):

  • 一个用于将图像转换为灰度图

  • 一个用于将图像恢复为原始彩色图

  • 一个用于将图像进行翻转

  • 一个用于将图像进行旋转

4.当用户点击按钮时,相应地更新窗口中显示的图像。

整体结构

  1. 加载 UI 文件:使用 uic.loadUi('./demo1.ui', self) 加载名为 demo1.ui 的 UI 文件,该文件定义了图形界面的布局和组件。
  2. 获取 UI 组件:通过 UI 文件中的对象名获取各个组件,包括一个用于显示图像的标签 self.lab 和四个用于触发不同操作的按钮 self.btn1、self.btn2、self.btn3、self.btn4。
  3. 加载图像:使用 cv2.imread('../1iamge/a.jpg') 从指定路径加载一张彩色图像,并将其存储在 self.img 中。
  4. 连接信号与槽 :将每个按钮的 clicked 信号连接到相应的槽函数。
    1. self.btn1.clicked.connect(self.gray):当 btn1 被点击时,调用 gray 方法将图像转换为灰度图。
    2. self.btn2.clicked.connect(self.show_img):当 btn2 被点击时,调用 show_img 方法显示当前图像。
    3. self.btn3.clicked.connect(self.flip_image):当 btn3 被点击时,调用 flip_image 方法水平翻转图像。
    4. self.btn4.clicked.connect(self.rotate_image):当 btn4 被点击时,调用 rotate_image 方法将图像旋转 90 度。

灰度转换方法 gray

  1. 转换为灰度图:使用 cv2.cvtColor(self.img, cv2.COLOR_BGR2GRAY) 将彩色图像转换为灰度图。
  2. 获取灰度图尺寸和字节数:获取灰度图的高度和宽度,计算每行的字节数。
  3. 创建并设置QPixmap:从灰度图的 QImage 创建 QPixmap,并将其设置到标签 self.lab 中显示,同时设置标签的内容自适应大小。

图像翻转:flip

  1. 水平翻转图像:使用 cv2.flip(self.img, 1) 对图像进行水平翻转,其中参数 1 表示水平方向翻转。
  2. 显示翻转后的图像:调用 show_img 方法显示翻转后的图像。

图像旋转:(getRotationMatrix2D,warpAffine)

  1. 计算旋转矩阵:使用 cv2.getRotationMatrix2D 计算旋转矩阵,以图像中心为旋转点,旋转角度为 90 度,缩放因子为 1。
  2. 应用旋转矩阵:使用 cv2.warpAffine 对图像应用旋转矩阵,实现图像旋转。
  3. 显示旋转后的图像:调用 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

  1. 获取图像尺寸和字节数 :获取传入图像的高度、宽度和通道数,计算每行的字节数。
  2. 转换图像格式 :将 OpenCV 的 BGR 格式图像转换为 QImage 格式,并将颜色通道从 BGR 转换为 RGB。
  3. 创建并设置 QPixmap :从 QImage 创建 QPixmap,并将其设置到标签 self.lab 中显示,同时设置标签的内容自适应大小。

亮度调整方法 update_brightness

  1. 复制图像 :对原始图像进行复制,得到 self.img_copy1,以避免直接修改原始图像。
  2. 调整亮度 :使用 cv2.convertScaleAbs 函数,通过设置 alpha=1 和 beta=value(value 为滑动条的值)来调整图像亮度。
  3. 显示调整后的图像 :调用 self.show_img(self.img_copy1) 显示调整亮度后的图像。

对比度调整方法 update_contrast

  1. 复制图像 :对原始图像进行复制,得到 self.img_copy2,以避免直接修改原始图像。
  2. 计算对比度因子 :根据滑动条的值 value 计算对比度因子 alpha = 1 + value / 100.0。
  3. 调整对比度 :使用 cv2.convertScaleAbs 函数,通过设置 alpha 和 beta=0 来调整图像对比度。
  4. 显示调整后的图像 :调用 self.show_img(self.img_copy2) 显示调整对比度后的图像。

图像保存方法 save_image

  1. 获取保存路径 :使用 QFileDialog.getSaveFileName 弹出文件保存对话框,让用户选择保存路径和文件名。
  2. 保存图像 :如果用户选择了保存路径(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())

结果:

相关推荐
jionghan385523 分钟前
理想的未来在AI——李想深度解析理想汽车的智能化之路
人工智能·汽车
WongKyunban26 分钟前
什么是机器学习
人工智能·机器学习
lovane_63029 分钟前
头歌-机器学习在 NLP 中的实战
人工智能·机器学习·自然语言处理
怎么就重名了30 分钟前
python opencv的orb特征检测(Oriented FAST and Rotated BRIEF)
开发语言·python·opencv
该醒醒了~30 分钟前
Yolo算法中特征相似导致误报问题
人工智能·算法·yolo
程序猿阿伟39 分钟前
《多模态融合:开启智能新时代的钥匙》
人工智能
jionghan38551 小时前
小米在AI大模型和GPU万卡集群领域的布局
人工智能
云空1 小时前
《计算机视觉:开启智能感知新时代》
人工智能·深度学习·神经网络·计算机视觉
电报号dapp1191 小时前
链游破局之路:如何打破边缘化,获得更好的发展
人工智能·去中心化·区块链·智能合约
兰特RR2 小时前
卷积神经网络(CNN)模型 CIFAR-10 数据集 例子
人工智能·神经网络·cnn