当前位置: 首页 > article >正文

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 方法显示旋转后的图像。

完整代码

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=valuevalue 为滑动条的值)来调整图像亮度。
  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,但实际应该是调整后的图像,这里代码存在问题)保存到指定路径。

完整代码

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 组件和变量: 
# 将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方法:
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方法:
def show_img(self):
    self.change_img(self.img)
4、显示原始图像。
  • Blur_img方法:
def Blur_img(self):
    self.img_blur = cv2.GaussianBlur(self.img, (5, 5), 150)
    self.change_img(self.img_blur)
5、使用高斯模糊对图像进行模糊处理,并显示处理后的图像。
  • Sharpen_img方法:
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方法:

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、获取下拉列表选择并处理:
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()

完整代码

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())

 结果:


http://www.kler.cn/a/461145.html

相关文章:

  • 蓝耘平台使用InstantMesh‌生成高质量的三维网格模型!3D内容创作!小白入门必看!!!
  • 微信小程序获取后端数据
  • GDPU 数据库原理 期末复习
  • 迅为RK3568开发板编译Android12源码包-设置屏幕配置
  • 庐山派K230学习日记1 从点灯到吃灰
  • MySQL面试题(updating)
  • 2024年12月31日Github流行趋势
  • ThreadLocal的概述,及如何避免内存泄漏
  • 【优选算法 分治】深入理解分治算法:分治算法入门小专题详解
  • 【持续集成与持续部署(CI/CD)工具 - Jenkins】详解
  • PHP 中的魔术常量
  • BurstAttention:高效的分布式注意力计算框架
  • GPU 进阶笔记(一):高性能 GPU 服务器硬件拓扑与集群组网
  • SOLID-开闭原则
  • 【连续学习之ResCL算法】2020年AAAI会议论文:Residual continual learning
  • 离散数学 群(半群,群,交换群,循环群,对称群,置换群,置换,交代群,轮换)详细,复习笔记
  • LeetCode热题100-反转链表【JavaScript讲解】
  • 【每日学点鸿蒙知识】Json字典问题、高度变化问题、开放测试版本问题、动态库单架构选择、WebView和H5交互
  • 【每日学点鸿蒙知识】人脸活体检测、NodeController刷新、自动关闭输入框、Row设置中间最大宽、WebView单例
  • JavaWeb 开发进阶 - 数据库交互与框架应用
  • 五、Hadoop环境搭建之模板虚拟机准备
  • tomcat窗口闪退,以及在eclipse上面运行不出来
  • HTML5滑块(Slider)
  • 从家谱的层级结构 - 组合模式(Composite Pattern)
  • es单机安装脚本自动化
  • hive-sql 计算每年在校生人数