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图像模糊的主要内容,如果未能解决你的问题,请参考以下文章