pyQT + OpenCV相关练习

news2025/5/18 7:15:00

一、设计思路

1、思路分析与设计

        本段代码是一个使用 PyQt6OpenCV 创建的图像处理应用程序。其主要功能是通过一个图形界面让用户对图片进行基本的图像处理操作,如灰度化、翻转、旋转、亮度与对比度调整,以及一些滤镜效果(模糊、锐化、边缘检测等)。应用程序的核心思想是将图像通过不同的算法进行处理,并通过一个图形用户界面与用户进行交互。

2、主要设计思路:

界面设计

        通过 PyQt6 提供的 QWidget 基础类构建一个窗口界面。

        在界面中使用了 QLabel 显示图像,使用 QPushButton 实现用户操作按钮,使用 QSlider 控制图像亮度和对比度,使用 QComboBox 提供滤镜选择。

图像加载与转换

        使用 OpenCVcv2.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 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


# 创建一个继承自QWidget的自定义窗口类
class MyWidget(QWidget):
    def __init__(self):
        super().__init__()

        # 加载并初始化UI文件
        ui = uic.loadUi("./Form.ui", self)

        # 加载初始图片,并为其创建副本和QImage对象
        self.img = cv2.imread("../demo.png")  # 读取图片
        self.img_2 = self.img.copy()  # 创建图片副本,用于亮度和对比度调整
        self.q_img = self.Qimg(self.img)  # 将OpenCV格式的图像转换为QImage格式

        # 初始化UI组件,包括标签、按钮、滑块等
        self.label: QLabel = ui.label
        self.pushButton: QPushButton = ui.pushButton
        self.pushButton_2: QPushButton = ui.pushButton_2
        self.pushButton_3: QPushButton = ui.pushButton_3
        self.pushButton_4: QPushButton = ui.pushButton_4

        self.horizontalSlider: QSlider = ui.horizontalSlider  # 亮度滑块
        self.horizontalSlider.setRange(0, 50)  # 设置亮度调整范围
        self.horizontalSlider.setValue(0)  # 设置默认亮度值为0

        self.horizontalSlider_2: QSlider = ui.horizontalSlider_2  # 对比度滑块
        self.horizontalSlider_2.setRange(1, 100)  # 设置对比度调整范围
        self.horizontalSlider_2.setValue(1)  # 设置默认对比度值为1

        self.pushButton_5: QPushButton = ui.pushButton_5  # 保存按钮
        self.comboBox: QComboBox = ui.comboBox  # 下拉框,用于选择滤镜效果

        # 连接按钮的点击事件到相应的槽函数
        self.pushButton.clicked.connect(self.gray_image)  # 点击“灰度化”按钮
        self.pushButton_2.clicked.connect(self.rec)  # 点击“恢复”按钮
        self.pushButton_3.clicked.connect(self.flip)  # 点击“翻转”按钮
        self.pushButton_4.clicked.connect(self.warp)  # 点击“旋转”按钮
        self.horizontalSlider.valueChanged.connect(self.bright)  # 亮度滑块改变时
        self.horizontalSlider_2.valueChanged.connect(self.bright)  # 对比度滑块改变时
        self.pushButton_5.clicked.connect(self.save)  # 点击“保存”按钮
        self.comboBox.currentIndexChanged.connect(self.dispose)  # 选择滤镜时

        # 为下拉框添加滤镜选项
        list1 = [' ','模糊', '锐化', '边缘检测']
        self.comboBox.addItems(list1)

        # 将QImage转换为QPixmap并设置为label的图片显示
        self.label.setPixmap(QPixmap.fromImage(self.q_img))
        self.label.setScaledContents(True)  # 设置图片自适应标签大小

        # 设置标志位,用于判断是否已经应用灰度化
        self.slot = False

    # 图片转换函数,将OpenCV格式的BGR图片转换为QImage格式
    def Qimg(self, img):
        img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)  # 将BGR图像转换为RGB
        h, w, c = img_rgb.shape  # 获取图像的高度、宽度和通道数
        bytes_per_line = c * w  # 每行字节数
        q_img = QImage(img_rgb.data, w, h, bytes_per_line, QImage.Format.Format_RGB888)  # 转换为QImage
        return q_img

    # 定义将图片灰度化的按钮响应函数
    def gray_image(self):
        if not self.slot:  # 判断是否已经灰度化过
            self.img = cv2.cvtColor(self.img, cv2.COLOR_BGR2GRAY)  # 将图片转换为灰度图
            q_img = self.Qimg(self.img)  # 转换为QImage格式
            self.label.setPixmap(QPixmap.fromImage(q_img))  # 更新显示的图片
            self.slot = True  # 更新标志位,表示已经灰度化

    # 定义恢复原图的按钮响应函数
    def rec(self):
        self.img = cv2.imread('../demo.png')  # 重新加载原始图片
        self.q_img = self.Qimg(self.img)  # 转换为QImage格式
        self.label.setPixmap(QPixmap(self.q_img))  # 更新显示的图片
        self.slot = False  # 重置标志位,表示恢复为原图

    # 定义图片翻转的按钮响应函数
    def flip(self):
        self.img = cv2.flip(self.img, 1)  # 进行水平翻转
        self.q_img = self.Qimg(self.img)  # 转换为QImage格式
        self.label.setPixmap(QPixmap.fromImage(self.q_img))  # 更新显示的图片

    # 定义图片旋转的按钮响应函数
    def warp(self):
        M = cv2.getRotationMatrix2D((self.img.shape[1] / 2, self.img.shape[0] / 2), 90, 1)  # 获取旋转矩阵
        self.img = cv2.warpAffine(self.img, M, (self.img.shape[1], self.img.shape[0]))  # 应用旋转
        self.q_img = self.Qimg(self.img)  # 转换为QImage格式
        self.label.setPixmap(QPixmap.fromImage(self.q_img))  # 更新显示的图片

    # 定义亮度和对比度调整的函数
    def bright(self):
        brightness = self.horizontalSlider.value()  # 获取当前亮度值
        contrast = self.horizontalSlider_2.value() / 100 + 1  # 获取当前对比度值,范围在1到2之间

        img_copy = contrast * self.img_2 + brightness  # 应用对比度和亮度调整
        img_copy = np.clip(img_copy, 0, 255)  # 保证像素值在0到255之间
        img_copy = np.uint8(img_copy)  # 转换为无符号8位整数类型
        self.img = img_copy  # 更新图片
        self.q_img = self.Qimg(self.img)  # 转换为QImage格式
        self.label.setPixmap(QPixmap.fromImage(self.q_img))  # 更新显示的图片

    # 定义保存图片的函数
    def save(self):
        cv2.imwrite('./img.png', self.img)  # 保存当前图片到本地文件

    # 根据选择的滤镜效果处理图片
    def dispose(self):
    # - 模糊——使用cv2.GaussianBlur()实现
    # - 锐化——使用cv2.Laplacian()、cv2.Sobel()实现
    # - 边缘检测——使用cv2.Canny()实现
        if self.comboBox.currentText() == ' ':
            self.rec()
        elif self.comboBox.currentText() == '模糊':
            self.img = cv2.GaussianBlur(self.img, (5, 5), 0)
            self.q_img = self.Qimg(self.img)  # 转换为QImage格式
            self.label.setPixmap(QPixmap.fromImage(self.q_img))
        elif self.comboBox.currentText() == '锐化':
            self.img = cv2.Laplacian(self.img, cv2.CV_64F)
            self.img = cv2.convertScaleAbs(self.img)
            self.q_img = self.Qimg(self.img)  # 转换为QImage格式
            self.label.setPixmap(QPixmap.fromImage(self.q_img))  # 更新显示的图片
        elif self.comboBox.currentText() =='边缘检测':
            M = cv2.Canny(self.img, 100, 200)  # 应用Canny边缘检测算法
            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.q_img = self.Qimg(self.img)  # 转换为QImage格式
            self.label.setPixmap(QPixmap.fromImage(self.q_img))  # 更新显示的图片



# 主程序入口
if __name__ == '__main__':
    app = QApplication(sys.argv)  # 创建应用对象
    myWidget = MyWidget()  # 创建自定义窗口对象
    myWidget.show()  # 显示窗口
    sys.exit(app.exec())  # 进入应用的事件循环

四、效果展示

原始界面

灰度化

恢复

翻转

旋转

亮度

对比度

模糊

锐化

边缘检测

保存

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2267358.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Git_bugs】remote error GH013 Repository rule violations found for.md

背景 1 在一个分支上的提交顺序如下:-> 代表新的提交 在提交 E 中,文件包含了 GitHub 生成的 token提交 F 是一次普通的提交,不包含 token A -> ... -> E -> F (敏感信息在 E 中)附:给提交起名是为了方便说明问题。…

Day1 微服务 单体架构、微服务架构、微服务拆分、服务远程调用、服务注册和发现Nacos、OpenFeign

目录 1.导入单体架构项目 1.1 安装mysql 1.2 后端 1.3 前端 2.微服务 2.1 单体架构 2.2 微服务 2.3 SpringCloud 3.微服务拆分 3.1 服务拆分原则 3.1.1 什么时候拆 3.1.2 怎么拆 3.2 拆分购物车、商品服务 3.2.1 商品服务 3.2.2 购物车服务 3.3 服务调用 3.3.1 RestTemplate 3.…

安卓执法仪Android接入国标GB28181平台实现实时监控、对讲、报警、定位等管理方案

最近协助不少企业完成了4G无线设备国标接入的需求,尤其是国产芯片的接入,国标发展了十年的时间,目前协议从完成度、性能、AI等各个方面,都已经非常完美地满足各种各样的场景需求,尤其是GB28181-2022的推出,…

SpringMVC学习(二)——RESTful API、拦截器、异常处理、数据类型转换

一、RESTful (一)RESTful概述 RESTful是一种软件架构风格,用于设计网络应用程序。REST是“Representational State Transfer”的缩写,中文意思是“表现层状态转移”。它基于客户端-服务器模型和无状态操作,以及使用HTTP请求来处理数据。RES…

国内独立开发者案例及免费送独立开发蓝图书

独立开发者在国内越来越受到关注,他们追求的是一种自由且自给自足的工作状态。 送这个: 少楠light(Flomo、小报童、如果相机):他们是独立开发者的典范,不仅开发了多款产品,还坚信“剩者为王”…

【JavaEE进阶】@RequestMapping注解

目录 📕前言 🌴项目准备 🌲建立连接 🚩RequestMapping注解 🚩RequestMapping 注解介绍 🎄RequestMapping是GET还是POST请求? 🚩通过Fiddler查看 🚩Postman查看 …

一文详解MacOS+CLion——构建libtorch机器学习开发环境

对于希望在本地环境中进行深度学习开发的开发者来说,配置合适的工具链是至关重要的一步。本文旨在帮助您在 macOS 操作系统上,利用 CLion IDE 和 PyTorch 的 C依赖库——libtorch,快速搭建起一个高效的开发环境。这里我们将一步步地讲解如何下…

Bert中文文本分类

这是一个经典的文本分类问题,使用google的预训练模型BERT中文版bert-base-chinese来做中文文本分类。可以先在Huggingface上下载预训练模型备用。https://huggingface.co/google-bert/bert-base-chinese/tree/main 我使用的训练环境是 pip install torch2.0.0; pi…

shardingsphere分库分表项目实践5-自己用java写一个sql解析器+完整项目源码

前1节我们介绍了 shardingsphere 分表分库的sql解析与重写: shardingsphere分库分表项目实践4-sql解析&重写-CSDN博客 那么shardingsphere sql 解析底层究竟是怎么实现的呢,其实它直接用了著名的开源软件 antlr . antlr 介绍: ANTLR&a…

10分钟掌握项目管理核心工具:WBS、甘特图、关键路径法全解析

一、引言 在项目管理的广阔天地里,犹如一场精心编排的交响乐演奏,每个乐器、每个音符都需精准配合才能奏响美妙乐章。而 WBS(工作分解结构)、甘特图、关键路径法无疑是这场交响乐中的关键乐章,它们从不同维度为项目管…

【LLM】OpenAI 的DAY12汇总和o3介绍

note o3 体现出的编程和数学能力,不仅达到了 AGI 的门槛,甚至摸到了 ASI(超级人工智能)的边。 Day 1:o1完全版,开场即巅峰 12天发布会的开场即是“炸场级”更新——o1完全版。相比此前的预览版本&#x…

使用Kubernetes部署MySQL+WordPress

目录 前提条件 部署MySQL和WordPress 编写yaml文件 应用yaml文件 存在问题及解决方案 创建PV(持久化卷) 创建一个PVC(持久化卷声明) 部署添加PVC 查看PV对应的主机存储 删除资源 查看资源 删除deployment和service 查看主机数据 删除PVC和PV 删除主机数据 前提条…

RabbitMQ中的异步Confirm模式:提升消息可靠性的利器

在现代分布式系统中,消息队列(Message Queue)扮演着至关重要的角色,它能够解耦系统组件、提高系统的可扩展性和可靠性。RabbitMQ作为一款广泛使用的消息队列中间件,提供了多种机制来确保消息的可靠传递。其中&#xff…

sentinel限流+其他

quick-start | Sentinel sentinel 作用 限流 熔断降级 1,限制什么 QPS 并发线程数 2,限制什么 资源,什么资源 服务,方法,接口,或者一段代码 3,实现方式 配置规则 注解 其他 Java常见5种限流…

Ubuntu 中安装 RabbitMQ 教程

简介 RabbitMq作为一款消息队列产品,它由Erlang语言开发,实现AMQP(高级消息队列协议)的开源消息中间件。 应用场景 异步处理 场景说明:用户注册后,注册信息写入数据库,再发邮件、短信通知。 …

Spark生态圈

Spark 主要用于替代Hadoop中的 MapReduce 计算模型。存储依然可以使用 HDFS,但是中间结果可以存放在内存中;调度可以使用 Spark 内置的,也可以使用更成熟的调度系统 YARN 等。 Spark有完善的生态圈: Spark Core:实现了…

AT24C02学习笔记

看手册: AT24Cxx xx代表能写入xxK bit(xx K)/8 byte 内部写周期很关键,代表每一次页写或字节写结束后时间要大于5ms(延时5ms确保完成写周期),否则时序会出错。 页写:型不同号每一页可能写入不同大小的…

119.【C语言】数据结构之快速排序(调用库函数)

目录 1.C语言快速排序的库函数 1.使用qsort函数前先包含头文件 2.qsort的四个参数 3.qsort函数使用 对int类型的数据排序 运行结果 对char类型的数据排序 运行结果 对浮点型数据排序 运行结果 2.题外话:函数名的本质 1.C语言快速排序的库函数 cplusplus网的介绍 ht…

五模型对比!Transformer-GRU、Transformer、CNN-GRU、GRU、CNN五模型多变量时间序列预测

目录 预测效果基本介绍程序设计参考资料 预测效果 基本介绍 光伏功率预测!五模型对比!Transformer-GRU、Transformer、CNN-GRU、GRU、CNN五模型多变量时间序列预测(Matlab2023b 多输入单输出) 1.程序已经调试好,替换数据集后,仅运…

利用Dockerfile构建自定义镜像

当一个系统开发完成,需要将系统打包为一个镜像文件,让docker能够运行该镜像,成为一个可以被访问的容器。 上述操作可以通过自定义镜像的方式来实现,本文章基于VMware虚拟机中安装的Centos7操作系统来完成。前面的操作步骤&#x…