Python+opencv学习记录8:边缘保留滤波(EPF)

1.高斯双边模糊

1.1原理

前文提到的高斯模糊只考虑了像素空间的分布,而没有考虑差异问题。高斯滤波在滤波时会将图像中各个颜色区域的边缘同区域本身一同模糊掉,而高斯双边滤波则是对各个区域的交界边缘有所保留。
若想了解其更深的原理,可以参考以下两篇文章:
http://www.360doc.com/content/17/0306/14/28838452_634420847.shtml
https://blog.csdn.net/edogawachia/article/details/78837988

1.2代码解析

在进行高斯双边模糊时,我们会用到bilateralFilter这个API,其参数有:
src:输入图像;
dst:输出图像;
d:表示在过滤过程中每个像素邻域的直径范围。如果这个值是非正数,则函数会从第五个参数sigmaSpace计算该值;
sigmaColor:颜色空间过滤器的sigma值,这个参数的值越大,表明该像素邻域内有越宽广的颜色会被混合到一起,产生较大的半相等颜色区域;
sigmaSpace:坐标空间中滤波器的sigma值,如果该值较大,则意味着越远的像素将相互影响,从而使更大的区域中足够相似的颜色获取相同的颜色。当d>0时,d指定了邻域大小且与sigmaSpace无关,否则d正比于sigmaSpace。
高斯双边模糊代码如下:

def bi_demo(image):                                 # 高斯双边模糊
    dst = cv.bilateralFilter(image, 0, 100, 15)
    cv.imshow("bi_demo", dst)

原图为:
在这里插入图片描述
经过双边模糊后:
在这里插入图片描述
可以看出黑白玄翦周围的火焰就像是被磨掉了一样,或者就像是油画里的场景一样,而剑身和剑的边缘依然被保留,并且天行九歌这四个字也被保留了下来。

如果还不够直观,我们可以在换一张图像来看一下,原图为:
在这里插入图片描述
经过双边滤波后:
在这里插入图片描述
此时,可以非常清楚地看见图像中的汗水大部分被滤掉了,而皮肤的效果最为明显,就像换了一张皮,并且脸的轮廓都被保留了下来,而没有像高斯模糊或者均值模糊、中值模糊那样把整张图像给模糊掉。

2.均值迁移模糊

2.1.原理

均值迁移模糊是图像边缘保留滤波算法中的一种,经常用在对图像进行分水岭分割之前去噪声,可以大幅度提升分水岭分割的效果。均值迁移模糊的主要思想如下: 就是在图像进行开窗的时候,考虑像素值空间范围分布,只有符合分布的像素点才参与计算,计算得到像素均值与空间位置均值,使用新的均值位置作为窗口中心位置继续基于给定像素值空间分布计算均值与均值位置,如此不断迁移中心位置直到不再变化位置(dx=dy=0),但是在实际情况中我们会人为设置一个停止条件比如迁移几次,这样就可以把最后的RGB均值赋值给中心位置。

在n维空间中,有一定数量的样本,我们选定其中的一个样本,以该样本为中心,给长度为半径画一个圆,求取该圆形区域内样本的质心,即密度最大的点,再以该点为中心继续执行上述迭代过程,直至最终收敛。

2.2.代码解析

在进行均值迁移模糊时,我们会用到pyrMeanShiftFiltering这个API,其参数如下:
src:输入图像;
dst:输出图像;
sp:定义迁移物理空间的半径大小;
sr:定义迁移色彩空间的半径大小;
maxLevel:定义金字塔的最大层数;
termcrit:定义的迁移迭代终止条件,可以设置为迭代次数满足终止,迭代目标与中心点偏差满足终止,或者两者的结合。
注:以上参数中最后两个很少用到,主要是sp和sr两个参数,二者设置的值越大,对图像色彩的平滑效果越明显,同时函数耗时越多。
均值迁移模糊的代码如下:

def shift_demo(image):                              # 均值迁移模糊
    dst = cv.pyrMeanShiftFiltering(image, 5, 50)
    cv.imshow("shift_demo", dst)

原图为:
在这里插入图片描述
经过滤波后:
在这里插入图片描述
相比较于高斯双边模糊,均值迁移模糊的效果给人一种磨皮过度的感觉,滤波后的图像就像是油画一样。

完整代码

import cv2 as cv                # 导入opencv模块
import numpy as np              # 导入数学函数库


def bi_demo(image):                                 # 高斯双边模糊
    dst = cv.bilateralFilter(image, 0, 100, 15)
    cv.imshow("bi_demo", dst)


def shift_demo(image):                              # 均值迁移模糊
    dst = cv.pyrMeanShiftFiltering(image, 5, 50)
    cv.imshow("shift_demo", dst)


print("------------hello python!------------")

# src = cv.imread("D:/opencv3/image/xuanjian.jpg")
src = cv.imread("D:/opencv3/image/example.png")
cv.namedWindow("input_image", cv.WINDOW_AUTOSIZE)
cv.imshow("input_image", src)
# bi_demo(src)
shift_demo(src)

cv.waitKey(0)
cv.destroyAllWindows()          # 释放所有窗口

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值