欢迎关注『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


















