山东大学软件学院2018级项目实训 第六周-UI终结者!
因为项目实训是一个比较长期的项目,所以我不会在每一周的总结中都贴上所有的代码,想要参考的同学需要结合前面几周涉及到的博客一起阅读!
第六周主要工作:
1.添加高斯模糊,中位模糊的功能和UI界面
2.添加形态变换中膨胀和腐蚀的功能和图形界面
在上周我们已经实现了均值模糊的图形界面:第五周均值模糊
这周的工作和上周内容步骤上相似,为项目再添加两个模块和四个新的功能
其中高斯模糊和中位模糊属于平滑图像部分
膨胀和腐蚀属于形态变换部分
1.高斯模糊
高斯模糊的opencv实现:
intstance.temp_image_blur = cv.GaussianBlur(intstance.m_image, (value, value), 0)
#value是高斯模糊的卷积核大小,可以通过鼠标拖动滑块发射信号得到value大小
滑块定义部分:
# 高斯模糊部分
# 创建一个滑动条
instance.sld_gaussian_blur = QSlider(Qt.Horizontal, instance.widegt_gaussian_blur)
instance.sld_gaussian_blur.setGeometry(30, 40, 100, 30)
#该滑动条拖动释放时发射信号
instance.sld_gaussian_blur.sliderReleased.connect(instance.signal_blur_emit)
# 为滑动条设置最小最大值,初始值等属性
instance.sld_gaussian_blur.setMinimum(3)
instance.sld_gaussian_blur.setMaximum(11)
instance.sld_gaussian_blur.setSingleStep(2)
instance.sld_gaussian_blur.setValue(3)
接收信号部分,这里会根据拖动滑块的信号来源判断其属于哪一个模块。
比如,如果信号是从图像→模糊→高斯模糊传来,就会对图像调用高斯模糊的函数
# 模糊图像信号发射函数
def signal_blur_emit(self):
# 获取信号源即滑动条的value
value = self.sender().value()
# 根据信号源的名字决定type的类型
if self.sender().objectName() == "mean_blur":
type = 0
if self.sender().objectName() == "gaussian_blur":
type = 1
if self.sender().objectName() == "median_blur":
type = 2
# 信号发射,执行该信号关联的函数
self.signal_processing_bar_blur.emit(self, type, value)
对应的具体实现代码在m_blur文件中:
(这个地方有个我花了很多时间才走出来的坑!)
就是objectName
是需要自己定义的,我原本以为self.sender().objectName()
会自动读取对象名然后对它进行判断,但其实这个地方是要提前声明的。这样对象名比如‘gaussian_blur’才能和if self.sender().objectName() == "gaussian_blur"
中的字符变量对应起来
# 设置object name,根据信号源的object name来选择下一步操作
instance.sld_mean_blur.setObjectName("mean_blur")
instance.sld_gaussian_blur.setObjectName("gaussian_blur")
instance.sld_median_blur.setObjectName("median_blur")
instance.sld_dilation_trans.setObjectName("dilation_trans")
instance.sld_erosion_trans.setObjectName("erosion_trans")
此外还需要再m_ui.py文件中添加显示高斯模糊窗口的函数
需要修改和添加的主要部分就是这些,下面看一下运行效果:
拖动滑块可以看到预览模糊效果
点击确定后,实际图片也被模糊
2.形态变换
形态变换部分的opencv实现:
import cv2 as cv
import numpy as np
img = cv.imread('j.png',0)
kernel = np.ones((5,5),np.uint8)
erosion = cv.erode(img,kernel,iterations = 1)
dilation = cv.dilate(img,kernel,iterations = 1)
这里偷了个懒,形态变换虽然和图像模糊是两个模块
但使用了图像模糊的步骤模板,比如
所以步骤和上述没有太大区别,唯一需要区分的地方是,形态变换是一个单独的菜单
# 添加一个菜单:模糊,这个菜单在后面被添加成图像选项的子选项
# 为该选项添加一个action blur_mean_action
change_menu1 = QMenu('模糊', instance)
change_menu1.addAction(blur_mean_action)
change_menu1.addAction(blur_gaussian_action)
change_menu1.addAction(blur_median_action)
#添加第二个菜单,形态变换
change_menu2 = QMenu('形态变换', instance)
change_menu2.addAction(trans_dilation_action)
change_menu2.addAction(trans_erosion_action)
直接看效果,为了方便对比这里换了一张图片,腐蚀:
膨胀:
下期预告:
1,把偷的懒补回来,图像模糊和形态变换是两个模块,最好还是分到两个文件中实现
2,代码有点冗余,做一下优化工作
3,实现阈值处理,直方图处理,sobel 拉普拉斯算子操作