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

0基础带你python入门:pyQT + OpenCV相关练习

一、思路分析

这个代码主要实现了一个基于 PyQt6OpenCV 的图像处理应用,能够加载图像并进行一系列处理,包括灰度化、旋转、翻转、图像增强(亮度、对比度调整)、模糊、锐化、边缘检测等操作。界面通过 PyQt6 进行构建,用户可以通过按钮、滑块和下拉框来控制图像处理效果。

具体实现的步骤可以分为以下几部分:

  1. 加载和显示图像
    使用 OpenCV 加载图像,并通过 cv2.QT_img 方法将图像转换为 Qt 支持的格式,以便在 QLabel 中显示。

  2. 图像预处理和效果实现
    通过不同的按钮和控件,进行图像的不同处理。按钮包括:

    • 灰度化(通过 gary_lot 方法)
    • 恢复原图(通过 rec_lot 方法)
    • 翻转(通过 flip_lot 方法)
    • 旋转(通过 spin_lot 方法)

    控件(滑块)控制亮度和对比度的调整,用户可以通过滑动条来调节图像的亮度和对比度。

  3. 特殊图像效果

    • 模糊:使用 cv2.blur 来实现模糊效果。
    • 锐化:使用高斯模糊后,再进行锐化处理。
    • 边缘检测:使用 Canny 边缘检测和 findContours 来提取图像的轮廓并绘制。
  4. 图像保存功能
    使用 cv2.imwrite 将当前图像保存为 img.png

二、设计到的函数和方法

  1. cv2_QT_img(self, img)

    • 功能:将 OpenCV 图像转换为 Qt 图像格式,并显示在界面上的 QLabel 中。
  2. gary_lot(self)

    • 功能:将图像转换为灰度图像并更新显示。
  3. rec_lot(self)

    • 功能:恢复原始图像。
  4. flip_lot(self)

    • 功能:水平翻转图像。
  5. spin_lot(self)

    • 功能:旋转图像 15 度。
  6. qslider_slot(self)

    • 功能:根据滑块的值调整图像的亮度和对比度。
  7. comboBoxr_slot(self)

    • 功能:根据下拉框选择不同的图像处理效果,分别为模糊、锐化和边缘检测。
  8. writer_slot(self)

    • 功能:将当前图像保存到本地文件 img.png

 三、代码

import cv2
import numpy as np
import sys
from PyQt6 import uic
from PyQt6.QtGui import QPixmap, QImage
from PyQt6.QtWidgets import QWidget, QApplication, QLabel, QPushButton, QSlider, QComboBox, QFileDialog

class MyWidget(QWidget):

    def cv2_QT_img(self, img):
        """将图像从 BGR 转换为 RGB 格式,并显示在 QLabel 中"""
        img_QT = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        h, w, c = img_QT.shape
        bytes_per_line = c * w
        q_img = QImage(img_QT.data, w, h, bytes_per_line, QImage.Format.Format_RGB888)

        self.label.setPixmap(QPixmap.fromImage(q_img))
        self.label.setScaledContents(True)
        return q_img

    def __init__(self):
        super().__init__()
        ui = uic.loadUi("./Form.ui", self)

        self.img_Boss = cv2.imread("./Lazy.png")
        self.img = self.img_Boss.copy()
        self.label: QLabel = ui.label

        # 显示初始图像
        self.cv2_QT_img(self.img)

        self.garyBtn: QPushButton = ui.garyBtn
        self.recBtn: QPushButton = ui.recBtn
        self.flipBtn: QPushButton = ui.flipBtn
        self.spinBtn: QPushButton = ui.spinBtn
        self.writer: QPushButton = ui.writer
        self.comboBox: QComboBox = ui.comboBox

        self.luminance: QLabel = ui.luminance
        self.contrast: QLabel = ui.contrast
        self.luSlider: QSlider = ui.luSlider
        self.conSlider: QSlider = ui.conSlider

        self.luSlider.setRange(-100, 100)
        self.conSlider.setRange(-100, 100)

        self.garyBtn.clicked.connect(self.gary_lot)
        self.gary_use = False

        self.recBtn.clicked.connect(self.rec_lot)
        self.flipBtn.clicked.connect(self.flip_lot)
        self.spinBtn.clicked.connect(self.spin_lot)
        self.writer.clicked.connect(self.writer_slot)

        list1 = ["原图", "模糊", "锐化", "边缘检测"]
        self.comboBox.addItems(list1)
        self.comboBox.currentIndexChanged.connect(self.comboBoxr_slot)

        self.luSlider.valueChanged.connect(self.qslider_slot)
        self.conSlider.valueChanged.connect(self.qslider_slot)

    def gary_lot(self):
        """灰度化图像"""
        if not self.gary_use:
            self.img = cv2.cvtColor(self.img, cv2.COLOR_BGR2GRAY)
            self.cv2_QT_img(self.img)
            self.gary_use = True

    def rec_lot(self):
        """恢复原始图像"""
        self.img = self.img_Boss.copy()
        self.cv2_QT_img(self.img)
        self.gary_use = False

    def flip_lot(self):
        """水平翻转图像"""
        self.img = cv2.flip(self.img, 1)
        self.cv2_QT_img(self.img)

    def spin_lot(self):
        """旋转图像"""
        M = cv2.getRotationMatrix2D((self.img.shape[1]//2, self.img.shape[0]//2), 15, 1)
        self.img = cv2.warpAffine(self.img, M, (self.img.shape[1], self.img.shape[0]))
        self.cv2_QT_img(self.img)

    def qslider_slot(self):
        """根据滑块调整亮度和对比度"""
        con_ = self.conSlider.value() / 100.0 + 1
        lu_ = self.luSlider.value()

        img_copy = cv2.convertScaleAbs(self.img_Boss, alpha=con_, beta=lu_)
        img_copy = np.clip(img_copy, 0, 255)
        self.img = img_copy
        self.cv2_QT_img(self.img)

    def comboBoxr_slot(self):
        """根据选项应用模糊、锐化或边缘检测"""
        if self.comboBox.currentText() == '模糊':
            self.img = cv2.GaussianBlur(self.img, (5, 5), 0)
            self.cv2_QT_img(self.img)
        elif self.comboBox.currentText() == '锐化':
            # 锐化操作
            kernel = np.array([[0, -1, 0], [-1, 5,-1], [0, -1, 0]])  # 锐化滤波器
            self.img = cv2.filter2D(self.img, -1, kernel)
            self.cv2_QT_img(self.img)
        elif self.comboBox.currentText() == '边缘检测':
            M = cv2.Canny(self.img, 100, 200)
            contours, h = cv2.findContours(M, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
            self.img = cv2.drawContours(self.img, contours, -1, (0, 255, 0), 3)
            self.cv2_QT_img(self.img)

    def writer_slot(self):
        # 通过 QFileDialog 弹出文件保存对话框
        file_path, _ = QFileDialog.getSaveFileName(
            self,  # 父窗口
            "保存文件",  # 对话框标题
            "",  # 默认路径
            "PNG文件 (*.png);;所有文件 (*.*)",  # 文件过滤器
        )

        if file_path:
            cv2.imwrite(file_path, self.img)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    myWidget = MyWidget()
    myWidget.show()
    sys.exit(app.exec())

 四、效果展示

原图 

 

灰度化:点击灰度化按钮后,图像将转为黑白色。

恢复原图:点击恢复按钮后,图像恢复为原始的彩色图像。


翻转:点击翻转按钮后,图像将左右镜像翻转。

旋转:点击旋转按钮后,图像会顺时针旋转 30 度。


亮度和对比度调节:使用滑块调节亮度和对比度,实时显示效果。


模糊:图像将变得模糊。


锐化:图像锐化,使边缘更清晰。


边缘检测:图像中的边缘部分会用绿色轮廓标出。

保存:将图片保存到到指定路径 


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

相关文章:

  • pandas删除值全部为0的整行和整列,还有0.0,0.000000也要删除
  • swiftui开发页面加载发送请求初始化@State变量
  • Android Room 框架的初步使用
  • 在基于IMX6ULL的Linux嵌入式编程中,与内存相关的堆(Heap)和栈(Stack)有什么区别?Linux 系统中堆和栈的内存布局是怎么样的?
  • Vscode左大括号不另起一行、注释自动换行
  • 开源电子书转有声书整合包ebook2audiobookV2.0.0
  • 调试文件系统(DebugFS )
  • Flutter 实现全局悬浮按钮学习
  • 微信小程序页面传参长度问题
  • Blender真实灰尘粒子动画资产预设 Dust Particles Pro V1.2
  • JVM常用参数
  • 《易经》在 Java 编程中的应用
  • Flutter 异步编程简述
  • 卷积神经网络(CNN)模型 CIFAR-10 数据集 例子
  • 学习,指针和FLASH
  • 02-18.python入门基础一基础算法
  • [江科大STM32] 第五集STM32工程模板——笔记
  • rk356x 下 qt 程序 hdmi不显示鼠标图标
  • 数值分析雨课堂章节测试
  • Java重要面试名词整理(十一):网络编程
  • 渗透测试常用术语总结
  • 深入了解JSON-LD:语义化网络数据的桥梁
  • v-if 和 v-show 的区别
  • anythingllm无法获取ollama模型
  • 在线学习平台-项目技术点-后台
  • 【计组】复习总结期末