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

Posted YouCans

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OpenCV-PyQT项目实战项目案例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项目实战(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

以上是关于OpenCV-PyQT项目实战项目案例01图像模糊的主要内容,如果未能解决你的问题,请参考以下文章

OpenCV-PyQT项目实战项目案例04:视频播放

OpenCV-PyQT项目实战项目案例03:鼠标定位

OpenCV-PyQT项目实战项目案例04:视频播放

OpenCV-PyQT项目实战项目案例02滚动条应用

OpenCV-PyQT项目实战项目案例02滚动条应用

OpenCV-PyQT项目实战项目案例03:鼠标框选