图像平滑处理,又叫做平滑滤波,或模糊滤波,能有效的过滤掉图像内部的噪声。其基本原理是图像像素点的值处理为邻域内其他像素点的均值。取近似的方法,即平滑滤波的方法多种多样。在空间滤波中,事先定义一个掩模,然后将掩模逐步移过像素点,掩模中心即当前像素点的值为掩模内所有像素点的值通过某种方式计算得到,掩模大小可以根据情况选择。但对于边界的点,由于其掩模有一部分在图像外围,所以此时要对其做一些特殊处理,常见的处理方法:
(1)控制掩模,使其在图像内部,对于边界的点对其不做滤波处理,或作部分滤波。
(2)在图像外围添加额外的行列进行补充,这些行与列的取值可以根据情况设定。
平均滤波就是像素点的值为掩模内所有像素的平均值。opencv提供的函数为cv2.blur()。语法格式:
dst=cv2.blur(src,ksize,anchor,borderType)
参数说明:
dst:目标输出图像
src:原始输入图像
ksize:空间滤波掩模大小
anchor:锚点,当前计算的像素点位于掩模的位置,默认为(-1,-1),表示位于掩模中心,一般使用默认值即可。
borderType:边界样式,即在滤波的时候对边界点的处理方式。一般采用默认值即可。
所以一般使用形式为:
dst=cv2.blur(src,ksize)
常见应用为图像去噪:
import cv2
image=cv2.imread("color_3.jpg")
blur=cv2.blur(image,(6,6))
cv2.imshow("image",image)
cv2.imshow("blur",blur)
cv2.waitKey(0)
cv2.destroyAllWindows()
运行结果:
方框滤波与平均滤波类似,只是其是先计算像素点邻域内像素值之后,然后可以自由选择是否求均值,即是否选择归一化。
opencv提供的方框滤波函数为cv2.boxFilter()。其语法格式:
dst=cv2.boxFilter(src,ddepth,ksize,anchor,normalize,borderType)
参数说明:
dst:目标输出图像
src:原始输入图像
ddepth:处理结果图像的图像深度,一般使用-1表示与原始图像相同的图像深度。
ksize:空间滤波掩模大小
anchor:锚点,当前计算的像素点位于掩模的位置,默认为(-1,-1),表示位于掩模中心,一般使用默认值即可。
normalize:在滤波时是否进行归一化处理,即是否求均值。为1时,进行归一化处理;为0时,不进行归一化处理。在不进行归一化处理时,结果可能会大于255,此时可能会进行截断处理,大于255的点全部置为255。所以默认值为1。
borderType:边界样式,即在滤波的时候对边界点的处理方式。一般采用默认值即可。
所以一般使用形式为:
dst=cv2.boxFilter(src,ddepth,ksize)
应用实例:
import cv2
image=cv2.imread("color_3.jpg")
#归一化
blur=cv2.boxFilter(image,-1,(6,6))
#非归一化
blur1=cv2.boxFilter(image,-1,(2,2),normalize=0)
cv2.imshow("image",image)
cv2.imshow("blur",blur)
cv2.imshow("blur1",blur1)
cv2.waitKey(0)
cv2.destroyAllWindows()
运行结果:
前面两种滤波方式中,掩模内所有像素的权重都是一致的。在高斯滤波,会根据像素点离掩模中心的距离来计算不同的权值,离中心近的权值高,离中心远的权值低。掩模的大小可以任意设定,但长于宽必须都是奇数。
opencv提供的函数为cv2.GaussianBlur(),语法格式:
dst=cv2.GaussianBlur(src,ksize,sigmax,sigmay,borderType)
参数说明:
dst:目标输出图像
src:原始输入图像
ksize:掩模大小
sigmax:高斯函数在x轴方向的标准差
sigmay:高斯函数在y轴方向的标准差
borderType:边界样式,即在滤波的时候对边界点的处理方式。一般采用默认值即可。
所以一般使用形式为:
注意:sigmax,sigmay为0时,此时可以让函数自己去计算对应的标准差的值,sigmax为必选参数,sigmay可以缺省。
应用实例:
import cv2
image=cv2.imread("color_3.jpg")
image=cv2.resize(image,(300,400))
#高斯滤波
blur=cv2.GaussianBlur(image,(9,9),0,0)
cv2.imshow("image",image)
cv2.imshow("blur",blur)
cv2.waitKey(0)
cv2.destroyAllWindows()
运行结果:
中值滤波是一种非线性滤波器,他的原理为:将掩膜内所有像素点值进行排序,然后用中位数(中值)来作为当前像素点的值。中值滤波的效果一般最好,因为噪声点的像素值一般很大,所以噪声点像素值一般不会被选上,因此他不像均值处理那样会改变原始图像的像素值分布。opencv提供的函数为:cv2.medianBlur(),语法格式:
dst=cv2.medianBlur(src,ksize)
参数说明:
dst:目标输出图像
src:原始输入图像
ksize:空间滤波掩模大小,为一正奇数,其掩模长和宽应一致。
应用实例:
import cv2
image=cv2.imread("color_3.jpg")
#高斯滤波
blur=cv2.medianBlur(image,7)
cv2.imshow("image",image)
cv2.imshow("blur",blur)
cv2.waitKey(0)
cv2.destroyAllWindows()
运行结果:
对于处于边界的像素点,即其左右像素值差异较大,运用上述的方法进行滤波,会使边界模糊,造成图像的边界信息丢失,双边滤波的思想就是解决这一问题。它的原理为:掩模内各点根据其与中心点距离的大小和像素值的差值综合赋予权值,离中心点越近,权值越大;与中心点像素值差别越大,权值越小。
opencv提供的函数为:cv2.bilateralFilter(),其语法格式:
dst=cv2.bilateralFilter(src,d,sigmaColor,sigmaSpace,borderType)
参数说明:
dst:目标输出图像
src:原始输入图像
d:滤波时空间距离参数,即以当前像素为中心,构造一个以d为直径的圆形掩模。如果为负数,则通过sigmaSpace计算得到。通常选择d=5;对于较大的离线噪声,可以选择d=9。
sigmaColor:颜色差值范围,在掩模内与中心点灰度值相差在sigmaColor范围内的点都可以参与滤波。
sigmaSpace:值越大,掩模范围越大,当d>0时,以d来决定掩模大小;当d<0时,通过sigmaSpace决定掩模大小,d与其成正比。
borderType:边界样式,即在滤波的时候对边界点的处理方式。一般采用默认值即可。
应用实例:
import cv2
image=cv2.imread("color_3.jpg")
#双边滤波
blur=cv2.bilateralFilter(image,35,200,200)
cv2.imshow("image",image)
cv2.imshow("blur",blur)
cv2.waitKey(0)
cv2.destroyAllWindows()
运行结果:
空间线性滤波的实质就是在做卷积,滤波器参数不同,滤波结果就会不同,有时我们可以自己设定一个特定的滤波器,对图像进行滤波,opencv中提供了cv2.filter2D()来实现滤波器与图像的卷积操作。其语法格式:
dst=cv2.filter2D(src,ddepth,kernel)
参数说明:
dst:目标输出图像
src:原始输入图像
ddepth:处理结果图像的图像深度,一般使用-1表示与原始图像相同的图像深度。
kernel:自定义滤波器,应为一个二维数组
应用实例:
import cv2
import numpy as np
image=cv2.imread("color_3.jpg")
kernel=np.ones((5,5))/25
#均值滤波
blur=cv2.blur(image,(5,5))
#自定义均值滤波
blur1=cv2.filter2D(image,-1,kernel)
cv2.imshow("blur",blur)
cv2.imshow("blur1",blur1)
cv2.waitKey(0)
cv2.destroyAllWindows()
运行结果:
上图为调用cv2.blur()进行均值滤波,和使用卷积自定义滤波,两者效果几乎一致。