OpenCV-PyQT项目实战(5)项目案例01:图像模糊

news2025/2/26 13:25:01

欢迎关注『OpenCV-PyQT项目实战 @ Youcans』系列,持续更新中
OpenCV-PyQT项目实战(1)安装与环境配置
OpenCV-PyQT项目实战(2)QtDesigner 和 PyUIC 快速入门
OpenCV-PyQT项目实战(3)信号与槽机制
OpenCV-PyQT项目实战(4)OpenCV 与PyQt的图像转换
OpenCV-PyQT项目实战(5)项目案例01:图像模糊
OpenCV-PyQT项目实战(6)项目案例02:滚动条应用
OpenCV-PyQT项目实战(7)项目案例03:鼠标框选

文章目录

  • OpenCV-PyQT项目实战(5)项目案例01图像模糊
    • 1. 项目需求
    • 2. 项目分析
    • 3. 使用 QtDesigner 开发 PyQt5 图形界面
      • 3.1 创建图形窗口(MainWindow)
      • 3.2 创建菜单对象(menu)
      • 3.3 创建工具栏对象(menu)
      • 3.4 创建内容显示控件(Label)
      • 3.5 创建按钮控件(PushButton)
    • 4. 项目主程序的开发
      • 4.1 打开图像文件子程序
      • 4.2 保存图像文件子程序
      • 4.3 OpenCV 图像文件转换为 QImage 子程序
      • 4.4 帮助菜单子程序
      • 4.5 按键动作的槽函数
      • 4.6 信号与槽的连接
      • 4.7 主程序
    • 5. 项目例程的测试


OpenCV-PyQT项目实战(5)项目案例01图像模糊

本节介绍一个 OpenCV-PyQt 项目案例。本项目虽然简单,但已经是一个完整的项目。


1. 项目需求

  • 读取并显示图像
  • 对图像进行灰度处理
  • 对图像进行模糊处理
  • 保存图像
  • 帮助
  • 关闭显示窗口


2. 项目分析

  • 使用OpenCV实现图像的读取,保存,灰度变换、模糊变换等图像处理操作;
  • 使用PyQt5创建GUI窗口,实现图像显示,实现用户交互;
  • 涉及OpenCV彩色图像、灰度图像与PyQt图像的转换


3. 使用 QtDesigner 开发 PyQt5 图形界面

使用 QtDesigner 开发 PyQt5 图形界面的基本步骤是:
(1)使用图形界面设计工具 QtDesigner 进行图形界面设计,生成 .ui 文件;
(2)使用 UI 转换工具 PyUIC 将 .ui 文件转换为 .py 文件;
(3)编写一个 Python 应用程序调用 .py 界面文件,就可以实现 Python 平台的 GUI 编程。


3.1 创建图形窗口(MainWindow)

(1)运行 PyCharm,打开建立的 Python Project,例如 Project 为 PyqtDemo。
(2)从顶部菜单栏选择:Tools -> ExternalTools -> QtDesigner,打开 QtDesigner。
(3)在 “新建窗体” 窗口的左侧菜单选择 “MainWindow” 新建一个图形窗口。
(4)在左侧上方 “对象查看器” 窗口选中 “MainWindow” 对象,在左侧中部 “属性编辑器” 编辑:

  • 将 “宽度” 修改为 800, “高度” 修改为 480,也可以直接使用鼠标拉伸来调整 “MainWindow” 大小。
  • 将 “WindowTitle” 属性修改为:OpenCV-PyQt Demo1。
  • 将 “WindowIcon” 属性修改为:用户选择的图标。

3.2 创建菜单对象(menu)

QtDesigner 创建的 “MainWindow” 图形窗口,自动生成了顶部菜单栏 menubar,在图形窗口左上角显示有文本输入框 “在这里输入”。

输入菜单对象(menu)的标题(title):

  • 鼠标点击文本输入框 “在这里输入”,选中文本输入框,控件的边框变为紫色;
  • 再双击选中的控件,出现激活的文本输入框,就可以输入所要建立菜单的标题;
  • 输入菜单标题后回车结束,就建立了一个一级菜单,例如:将菜单标题设为 “文件”。

输入菜单对象的标题,以及修改菜单对象的属性,更通用的方法是:

  • 在 QtDesigner 右侧的 “对象查看器” 中选中对象 “menu”,此时右侧中部的 “属性编辑器” 将显示对象 “menu” 的属性。
  • 在 “属性编辑器” 内选择 “title” 属性,将其修改为菜单标题:“文件”。

建立一级菜单 “文件” 后,菜单栏中在 “文件” 右侧又出现新的文本输入框 “在这里输入” ,按照以上操作可以接着建立更多的菜单对象。

QtDesigner 创建二级菜单,实际上是将动作(action)添加到一级菜单。


3.3 创建工具栏对象(menu)

工具栏/工具条是图形界面中的常用组件,将一组按钮控件排成一行放在图形窗口的顶部。

QtDesigner 中 添加工具栏:单击鼠标右键,选择 “添加工具栏”。添加工具栏以后,在顶部菜单栏的下方出现工具栏。新添加的工具栏是空的,非常窄。

工具栏中只能添加动作控件(QAction),因此要先添加/编辑动作。其实上文中菜单栏中也只能添加动作控件,但是菜单栏允许在输入二级菜单时直接添加动作控件(QAction),而工具栏只允许选择已有的动作控件添加。

在 QtDesigner 右侧下方窗口选择 “动作编辑器”,可以新建或编辑动作对象。添加编辑动作对象步骤为:

  • 点击 “动作编辑器” 子窗口工具栏的第一个图标按钮 “新建”,则弹出 “新建动作” 对话框;
  • 双击 “动作编辑器” 中的动作对象,则弹出 “编辑动作” 对话框,可以编辑已有动作对象的属性;

例程添加了动作对象:“actionOpen/打开”、“actionClose/关闭”、“actionSave/保存”、“actionSetup/设置”、“actionHelp/帮助”, “actionQuit/退出” 。

从 QtDesigner 右侧下方窗口选择 “动作编辑器”,鼠标左键点击选中其中的动作控件,长按鼠标不放,拖动到图形窗口的工具栏后松开,就将动作控件添加到工具栏中。

如果动作对象设有图标,则在工具栏显示动作图标;如果动作对象没有设置图标,则在工具栏显示动作标题的文本信息。

在这里插入图片描述


3.4 创建内容显示控件(Label)

在 QtDesigner 左侧的 “WidgetBox” 工具栏中,将常用的控件按类别进行分组。用鼠标将工具栏中的控件图标拖拽到 QtDesigner 中间的图形界面编辑窗口,就在图像界面创建了一个所选择的控件。

内容显示控件QLabel(显示框)是一个只读显示的简易控件,用于显示不可编辑的文本或图像,不提供用户交互功能。

  • 从左侧控件栏的 “DisplayWidget” 中选择 Label 控件,移动鼠标将 Label 控件拖动到新建图形窗口内的任意位置,就在图形窗口位置生成了一个 Label 控件对象。
  • 鼠标左键选中图形窗口中的这个 Label 控件对象,拖动鼠标可以调整控件的位置,对于其它控件也可以通过鼠标拖动来调整位置。
  • 对于添加到 QLabel 显示框,可以通过属性编辑器修改属性,例如通过 “Pixmap” 选择显示的图像文件。默认情况下,QLabel 会对 文本和图像 内容 左对齐、垂直居中显示,也可以通过属性修改进行设置。

类似地,建立 Label 控件对象 “label_2”,但没有为其设置显示的图像文件,因此该区域看起来是空白的。


3.5 创建按钮控件(PushButton)

按钮是最常用的控件类型。在 QtDesigner 左侧的 “WidgetBox” 工具栏中的"Buttons" 组,设有多种不同类型的按钮控件。

QPushButton(按键按钮)是最常用的按钮,按下(或者单击)按钮可以执行某个操作或回答问题,例如:确定,应用,取消,关闭,是,否和帮助。

  • 按钮控件通常显示一个文本标签(text),可以为按钮选择一个图标(icon),还可以选择设置快捷键(shortcut)。

  • 按键按钮的上述属性,都可以在 “属性编辑器” 中相应的属性行中进行编辑修改。

  • 当按键按钮被鼠标或快捷键激活时,按钮会发出 clicked() 信号,可以通过连接槽函数来触发特定的操作。

用鼠标将工具栏中的按钮控件拖拽到 QtDesigner 中间的图形界面编辑窗口,就在图像界面创建了一个按钮控件。如下图所示,我们在图形界面 uiDemo4.ui 的左侧,创建了几种不同的按钮控件。

从左侧控件栏的 “Buttons” 中选择 PushButton 按钮,移动鼠标将 PushButton 按钮拖动到新建图形窗口内的任意位置,就在图形窗口位置生成了一个 PushButton 按钮对象。

  • 鼠标左键选中图形窗口中的这个 PushButton 按钮对象,拖动鼠标可以调整控件的位置。
  • 鼠标选中 PushButton 按钮对象,控件周围的边界位置上就出现 8个蓝色的点,表示控件被选中,这时可以在右侧的 “属性编辑器” 内对对象的属性进行编辑和修改,例如:
    • 将 PushButton 对象的高度修改为 80,宽度修改为 40;
    • 将 PushButton 对象的 “QAbstractButton->text” 修改为 “1 打开”。

类似地,依次添加按钮控件:“1 打开”、“2 灰度”、“3 模糊”、“4 帮助”、“5 退出”


在这里插入图片描述

于是,我们就完成了本项目的图形界面设计,将其保存为 uiDemo4.ui文件。

在 PyCharm中,使用 PyUIC 将选中的 uiDemo4.ui 文件转换为 .py 文件,就得到了 uiDemo4.py 文件。



4. 项目主程序的开发

4.1 打开图像文件子程序

用 QFileDialog.getOpenFileName 函数交互式选择要打开的文件,用 cv.imread函数读取图像文件。

    def openSlot(self, flag=1):  # 读取图像文件
        # OpenCV 读取图像文件
        fileName, _ = QFileDialog.getOpenFileName(self, "Open Image", "../images/", "*.png *.jpg *.tif")
        if flag==0 or flag=="gray":
            img = cv.imread(fileName, cv.IMREAD_GRAYSCALE)  # 读取灰度图像
        else:
            img = cv.imread(fileName, cv.IMREAD_COLOR)  # 读取彩色图像
        print(fileName, img.shape)
        return img

4.2 保存图像文件子程序

用 QFileDialog.getSaveFileName 函数交互式选择要保存的文件名,用 cv.imwrite函数写入图像文件。

    def saveSlot(self):  # 保存图像文件
        # 选择存储文件 dialog
        fileName, tmp = QFileDialog.getSaveFileName(self, "Save Image", "../images/", '*.png; *.jpg; *.tif')
        if self.img1.size == 1:
            return
        # OpenCV 写入图像文件
        ret = cv.imwrite(fileName, self.img1)
        if ret:
            print(fileName, self.img.shape)
        return

4.3 OpenCV 图像文件转换为 QImage 子程序

    def cvToQImage(self, image):
        # 8-bits unsigned, NO. OF CHANNELS=1
        if image.dtype == np.uint8:
            channels = 1 if len(image.shape) == 2 else image.shape[2]
        if channels == 3:  # CV_8UC3
            # Create QImage with same dimensions as input Mat
            qImg = QImage(image, image.shape[1], image.shape[0], image.strides[0], QImage.Format_RGB888)
            return qImg.rgbSwapped()
        elif channels == 1:
            # Create QImage with same dimensions as input Mat
            qImg = QImage(image, image.shape[1], image.shape[0], image.strides[0], QImage.Format_Indexed8)
            return qImg
        else:
            QtCore.qDebug("ERROR: numpy.ndarray could not be converted to QImage. Channels = %d" % image.shape[2])
            return QImage()

4.4 帮助菜单子程序

    def trigger_actHelp(self):  # 动作 actHelp 触发
        QMessageBox.about(self, "About",
                          """数字图像处理工具箱 v1.0\nCopyright YouCans, XUPT 2023""")
        return

4.5 按键动作的槽函数

    def click_pushButton_1(self):  # 点击 pushButton_1 触发
        self.img1 = self.openSlot()  # 读取图像
        print("click_pushButton_1", self.img1.shape)
        self.refreshShow(self.img1, self.label_1)  # 刷新显示
        return

    def click_pushButton_2(self):  # 点击 pushButton_2 触发
        print("pushButton_2")
        self.img2 = cv.cvtColor(self.img1, cv.COLOR_BGR2GRAY)  # 图片格式转换:BGR -> Gray
        self.refreshShow(self.img2, self.label_2)  # 刷新显示
        # gray = cv.cvtColor(self.img1, cv.COLOR_BGR2GRAY)
        # self.refreshShow(gray, self.label_2)
        return

    def click_pushButton_3(self):  # 点击 pushButton_3 触发
        print("pushButton_3")
        # gray = cv.cvtColor(self.img1, cv.COLOR_BGR2GRAY)
        ksize = (11, 11)  # 高斯滤波器核的尺寸
        blur = cv.GaussianBlur(self.img1, ksize, 0)  # sigma 由 ksize 计算
        self.refreshShow(blur, self.label_2)  # 刷新显示
        return

4.6 信号与槽的连接

        # 通过 connect 建立信号/槽连接,点击按钮事件发射 triggered 信号,执行相应的子程序 click_pushButton
        # self.pushButton_1.clicked.connect(self.openSlot)  # 点击 pushButton_1 触发
        self.pushButton_1.clicked.connect(self.click_pushButton_1)  # 点击 pushButton_1 触发
        self.pushButton_2.clicked.connect(self.click_pushButton_2)  # 点击 pushButton_2 触发
        self.pushButton_3.clicked.connect(self.click_pushButton_3)  # 点击 pushButton_3 触发
        self.pushButton_4.clicked.connect(self.trigger_actHelp)  # 点击 pushButton_4 触发
        self.pushButton_5.clicked.connect(self.close)  # 点击 pushButton_5 关闭窗口

4.7 主程序

# OpenCVPyqt04.py
# Demo04 of GUI by PyQt5
# Copyright 2023 Youcans, XUPT
# Crated:2023-02-02

if __name__ == '__main__':
    app = QApplication(sys.argv)  # 在 QApplication 方法中使用,创建应用程序对象
    myWin = MyMainWindow()  # 实例化 MyMainWindow 类,创建主窗口
    myWin.show()  # 在桌面显示控件 myWin
    sys.exit(app.exec_())  # 结束进程,退出程序


5. 项目例程的测试

测试应用程序 OpenCVPyqt04.py的各项功能:

(1)运行 OpenCVPyqt04,弹出程序窗口,自动加载 Fig0301。

(2)点击 "4 帮助"按钮,弹出帮助信息提示框,点击 “OK” 可以关闭信息框。

在这里插入图片描述


(3)点击 “1 打开”,运行 click_pushButton_1 槽函数。选择目录路径和图像文件,读取图像并在窗口显示彩色图像。

在这里插入图片描述


(4)点击 "2 灰度"按钮,运行 click_pushButton_2 槽函数。在窗口右侧显示转换的灰度图像。

在这里插入图片描述


(5)点击 "3 模糊"按钮,运行 click_pushButton_3 槽函数。在窗口右侧显示高斯模糊处理的彩色图像。

在这里插入图片描述


(6)点击 "5 退出"按钮,关闭窗口。


【本节完】


版权声明:

Copyright 2023 youcans, XUPT

Crated:2023-2-2


【本节完】


版权声明:
原创作品,转载必须标注原文链接:https://blog.csdn.net/youcans/article/details/128845326
Copyright 2023 youcans, XUPT
Crated:2023-02-02

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

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

相关文章

PySpark实战一之入门

1、PySpark的编程模型 分三个模块: 数据输入:通过SparkContext对象,完成数据输入 数据处理计算:输入数据后得到RDD对象,对RDD对象的成员方法进行迭代计算 数据输出:最后通过RDD对象的成员方法&#xff0…

互联网行业固定资产智能化解决方案为企业降本增效

互联网行业的固定资产数量和种类往往比较多,来源可能是租赁、购入、调拨等。主要分为:办公设备、电子设备、服务器等。固定资产是互联网企业的重要资产之一,是企业持续经营的物质基础。因此,对于实物资产的管理尤为重要。 互联网…

搭建zookeeper高可用集群详细步骤

目录 一、虚拟机设置 1.新建一台虚拟机并克隆三台,配置自定义 2.修改四台虚拟机的主机名并立即生效 3.修改四台虚拟机的网络信息 4.重启四台虚拟机的网络服务并测试网络连接 5.重启四台虚拟机,启动后关闭四台虚拟机的防火墙 6.在第一台虚拟机的/e…

TripleCross:一款功能强大的Linux eBPF安全研究工具

关于TripleCross TripleCross是一款功能强大的Linux eBPF安全研究工具,该工具提供了后门、C2、代码库注入、执行劫持、持久化和隐蔽执行等功能。 功能介绍 1、使用一个代码库注入模块通过往进程的虚拟内存中写入命令来执行恶意代码; 2、提供了一个行劫…

波卡2022年第四季度报告

本文将介绍Messari最新发布的波卡Polkadot 2022年第四季度报告内容。 1 Messari已经发布关于波卡Polkadot最新的报告:显示了2022年第四季度的日活账户增加了64%,新用户增长49%。 2 Messari指出,波卡中继链在2022第四季度的环比增长令人印象…

JavaScript 保留关键字

文章目录JavaScript 保留关键字JavaScript 标准JavaScript 保留关键字JavaScript 对象、属性和方法Java 保留关键字Windows 保留关键字HTML 事件句柄非标准 JavaScriptJavaScript 保留关键字 在 JavaScript 中,一些标识符是保留关键字,不能用作变量名或函…

100行Pytorch代码实现三维重建技术神经辐射场 (NeRF)

提起三维重建技术,NeRF是一个绝对绕不过去的名字。这项逆天的技术,一经提出就被众多研究者所重视,对该技术进行深入研究并提出改进已经成为一个热点。不到两年的时间,NeRF及其变种已经成为重建领域的主流。本文通过100行的Pytorch…

部门新来个00后卷王,太让人崩溃了,想离职了....

在职场上,什么样的人最让人反感? 是技术不好的人吗? 并不是。技术不好的同事,我们可以帮他。 是技术太强的人吗? 也不是。技术很强的同事,可遇不可求,向他学习还来不及呢。 真正让人反感的…

【uniapp】getOpenerEventChannel().once 接收参数无效的解决方案

uniapp项目开发跨平台应用常会遇到接收参数无效的问题,无法判断是哪里出错了,这里是讲替代的方案,现有三种方案可选。 原因 一般我们是这样处理向另一个页面传参,代码是这样写的 //... let { title, type, rank } args; uni.n…

STM32 HAL库-定时器中断

STM32 HAL库-定时器中断一、STM32F407定时器介绍定时器计算公式二、CubeMX配置定时器三、基本定时器中断配置流程1)开启定时器时钟2)初始化定时器参数,设置自动重装值,分频系数,计数方式等3)使能定时器更新中断&#x…

Ubuntu 系统 OpenCV 4 无法打开视频文件解决方案

目录 一、我的运行环境 二、问题描述 三、问题定位及分析 四、解决方案 一、我的运行环境 设备NVIDIA Jetson Nano处理器ARMv8 Processor rev 1 (v8l) 4 GPUNVIDIA Tegra X1 (nvgpu)/integrated操作系统ubuntu 18.04 LTSOpenCV版本4.6.0语言C 二、问题描述 之前一直用的O…

8 冒泡排序

文章目录1 基本介绍1 代码实现1.1 java1.1 scala1 基本介绍 冒泡排序(Bubble Sorting)的基本思想是:通过对待排序序列从前向后(从下标较小的元素开始),依次比较相邻元素的值,若发现逆序则交换,使…

存储管理(6)

存储管理 1 程序的装入与链接 编译:源代码——目标代码 链接:目标代码所需库函数装入模块 装入:将装入模块装入内存,该过程也叫做地址重定位,也称地址映射 地址空间: 源程序经编译后得到的目标程序&…

Leetcode 1223. 掷骰子模拟【动态规划】

有一个骰子模拟器会每次投掷的时候生成一个 1 到 6 的随机数。 不过我们在使用它时有个约束,就是使得投掷骰子时,连续 掷出数字 i 的次数不能超过 rollMax[i](i 从 1 开始编号)。 现在,给你一个整数数组 rollMax 和一…

WebDAV之葫芦儿·派盘+NMM

NMM 支持WebDAV方式连接葫芦儿派盘。 推荐一款文件管理器,可以对手机中的文件进行多方面的管理,支持语法高亮和ftp等远程的文件的管理。支持从WebDav服务器连接葫芦儿派盘服务下载文件和上传文件。 NMM文本编辑器是一款文件管理器,在功能上面更加的适合于一些编程人员进行使…

2023年应该了解的黑客知识

网络犯罪的艺术处于不断变化和演变的状态。与这些趋势保持同步是网络安全人员工作的重要组成部分。 今天的现代网络安全必须确保他们始终为下一个大趋势做好准备并保持领先于对手。 当我们开始迈向 2023 年时,安全格局与一年前相比已经发生了变化,更不…

Spark on hive Hive on spark

文章目录Spark on hive & Hive on sparkHive 架构与基本原理Spark on hiveHive on sparkSpark on hive & Hive on spark Hive 架构与基本原理 Hive 的核心部件主要是 User Interface(1)和 Driver(3)。而不论是元数据库&a…

webpack(高级)--性能优化-代码分离

webpack webpack性能优化 优化一:打包后的结果 上线时的性能优化 (比如分包处理 减少包体积 CDN服务器) 优化二:优化打包速度 开发或者构建优化打包速度 (比如exclude cache-loader等) 大多数情况下我们侧…

css 安全区域 safe-area-inset-

前言 安全区域与边界是iOS11 新增特性。 安全区域 安全区域的内容不受圆角(corners)、齐刘海(sensor housing)、小黑条(Home Indicator)影响。Webkit 为此增加了相应的CSS 函数,用于获取安全…

B树系列与MySQL数据库

前篇提到B树及其实现:一文看懂---B树及其简单实现_b树实现_且随疾风前行->的博客-CSDN博客 本篇继续谈B树系列的B树,B*树和它们与MySQL数据库的关系。 目录 B树系列 B树 B树的特性: B*树 B树系列总结 MySQL索引简介 MyISAM Inno…