关于去燥的方法,在前两个博客中我们已经进行了初步的讨论,我么已经见证了中值滤波、均值滤波、自定义滤波和高斯滤波,也看到了他们都可以对噪声进行抑制。让我们接着上两节的问题继续思考,在对图像进行去燥时前两节提到的那四种滤波算法有没有什么不足呢。
我们对去燥之后的照片进行观察可以发现,前面的四种去燥方法的确抑制了噪声,但是同时也使图像本身变得更加朦胧了。当人物和背景同时存在时,人物和背景之间的界限也变得模糊不清了。这其实是和算法本身的局限性密切相关的,前面四种算法像是一个没有感情的机器人,对所有的像素点都是一视同仁,不管你是人像还是背景还是分界线,我的计算方法永远不变,上来先卷积了再说。这种类似中央空调似的做法,也就导致了人像、背景、边界混在一起,主次难辨了。
基于此,一种优化的滤波算法被设计了出来——边缘保留滤波。正如它的名字表明的那样,这种滤波算法可以把图像的边缘保留下来。
通过前面的探讨我们知道,滤波的本质是把图像和核函数进行相乘再求和,从这个层面来看,核函数更像是给图像点加了个权值。我们这样来想,当计算到距离边缘较近的点时,如果这个点属于人像,我们就把在背景部分的那些权值给置零,从而在模糊时参与计算的只有人像的像素点,背景部分虽然参与了卷积计算,但是由于核函数的权值为零,所有不对滤波结果产生影响。
于是,我们就知道了,与前面的几种滤波最大的区别是,前面几种滤波算法核函数的值是始终不变的。而边缘保留滤波(EPF)的核函数是时刻变化的。
为了更好的理解边缘保留滤波(EPF)的思想,我们可以来看一下边缘保留滤波(EPF)中最经典的一张图。
我们来看一下左上角的那个黄图。其中白色那个点就是像素点靠近边缘的情况。我们可以把比较高的那部分想象成像素值比较高的人像,比较低的那部分想象成像素值比较低的背景。这样在滤波的时候,人像那部分权值不为0,比较低的背景部分权值为0。这样只有人像部分参与了滤波。同理,在进行背景部分的滤波时也是这样。这样大家各玩各的,互不影响,边缘就被保留了下来。
OpenCV中给我们提供了两种实现边缘保留滤波的方法。
一种是:双边滤波(Bilateral filter)是一种非线性的滤波方法,是结合图像的空间邻近度和像素值相似度的一种折中处理,同时考虑空域信息和灰度相似性,达到保边去噪的目的。
另一种是:均值漂移滤波(pyrMeanShiftFiltering)这里要说明的是,在图像处理中均值漂移滤波常用来做图像分割。这是由于均值漂移滤波使用的是聚类算法,对于相近的颜色会使用一种颜色代替,最后会丢失大量的细节。
在百度图片库中选择一张图片如下:
在pycharm中编写如下的程序:
import cv2 as cv
image = cv.imread("ren.jpg")
cv.namedWindow("image show", cv.WINDOW_AUTOSIZE)
cv.namedWindow("gaussian image show", cv.WINDOW_AUTOSIZE)
cv.namedWindow("bilater image show", cv.WINDOW_AUTOSIZE)
cv.namedWindow("shift image show", cv.WINDOW_AUTOSIZE)
# 高斯模糊
gaussian = cv.GaussianBlur(image, (5, 5), 0)
# 双边滤波
bilater = cv.bilateralFilter(image, 0, 100, 15)
# 均值漂移滤波
shift = cv.pyrMeanShiftFiltering(image, 10, 50)
cv.imshow("image show", image)
cv.imshow("gaussian image show", gaussian)
cv.imshow("bilater image show", bilater)
cv.imshow("shift image show", shift)
cv.waitKey(0)
cv.destroyAllWindows()
运行程序,可得运行结果如下:
高斯模糊运行结果:
双边滤波运行结果:
均值漂移滤波运行结果:
对结果进行分析可知,边缘保留滤波(EPF)的滤波效果要明显好于高斯滤波,对边缘有更好的保留效果。
双边滤波在OpenCV中代码为:
bilateralFilter(src, d, sigmaColor, sigmaSpace, dst=None, borderType=None)
参数解析:
@参数src,源8位或浮点,1通道或3通道图像。
@参数dst,与src大小和类型相同的目标映像。
@参数d,滤波过程中使用的每个像素邻域的直径。如果为非正,则从sigmaSpace计算。
@参数sigmaColor,在颜色空间中过滤sigma。参数值越大,意味着像素邻域内的其他颜色(请参见sigmaSpace)将混合在一起,从而产生更大的半等色区域。
@参数sigmaSpace,在坐标空间中过滤sigma。参数值越大,意味着越远的像素将相互影响,只要它们的颜色足够接近(请参见sigmaColor)。当d>0时,它指定邻域大小,而不考虑sigmaSpace。否则,d与sigmaSpace成正比。
@参数 borderType,用于外推图像外部像素的边界模式,请参见#BorderTypes
均值漂移滤波在OpenCV中代码为:
pyrMeanShiftFiltering(src, sp, sr, dst=None, maxLevel=None, termcrit=None)
参数解析:
@参数src,源8位3通道图像。
@参数dst与源具有相同格式和大小的目标图像。
@参数sp,空间窗口半径。
@参数sr,颜色窗口半径。
@参数maxLevel,分段金字塔的最大级别。
@参数termcrit终止条件:何时停止meanshift迭代。