消除图像中的噪音成分,叫做图像的平滑处理或者图像滤波。即在尽量保留图像细节特征的情况下对目标图像的噪声进行抑制。它是图像预处理过程中不可缺少的步骤。处理效果的好坏将直接影响到后续图像处理的有效性和可靠性。
1、消除图像中混入的噪声。2、为图像识别抽取出图像特征。
1、不能损坏图像轮廓及边缘 。2、图像视觉效果应当更好。
实际使用:
图像的边缘非常容易收到噪声的干扰,所以为了避免检测到错误的边缘信息,通常需要对图像进行滤波以除去噪声。
图像平滑处理会对图像中与周围像素点的像素值差异较大的像素点进行处理,将其值调整为周围像素点像素值的近似值。取近似值的方式有很多,主要有:
均值滤波
方框滤波
高斯滤波
中值滤波
双边滤波
自定义滤波(2D卷积)
1. 均值滤波:
均值滤波是指用当前像素点周围NxN个像素值的均值来替代当前像素值。使用该方法遍历处理图像内每一个像素点。
1.1:首先要考虑对多大的区域取平均值。即NxN这个N取多少。例如:3x3. 5x5, 7x7.
这个值就是kernel size. 这个值越大,参与运算的像素点数量就会越多。图像失真就越严重。
1.2:对图像边缘,无法取这么大的区域,则有两种方法:
A:取周围不以目标点为中心的NxN个区域的均值。
B:扩展图像,让边缘点也可以做为中心点。
边界处理方法。
1.3:函数语法:
dst = cv.blur(src, ksize[, dst[, anchor[, borderType]]])
返回值,
dst: 均值滤波后得到的处理结果。
参数:
src: 需要处理的图像。
ksize: kernel大小。指在均值处理时,其相邻区域的高度和宽度。可以为(5,5), (7,7).
kernel越大,参与到均值运算的像素越多,去噪效果更好。 但图像的失真也越严重。
anchor:锚点。默认值为(-1, -1). 表示当前计算均值的点位于kernel的中心点位置。
borderType:边界式样。一般不指定,使用默认值。
1.4:例子:
import cv2 import numpy as np img = cv2.imread("images/ab.jpeg", cv2.IMREAD_COLOR) kernel_size = (3,3) img_blur = cv2.blur(img, kernel_size) cv2.imshow("Before", img) cv2.imshow("After", img_blur) cv2.waitKey(0) cv2.destroyAllWindows()
2. 方框滤波:
均值滤波是计算任意一个点的邻域平均值,即邻域像素值之和除以邻域面积。方框滤波则可以选择是否对结果进行归一化,即可以自由选择滤波的结果是邻域像素值之和的平均数,还是邻域像素值之和。
dst = cv.boxFilter(src, ddepth, ksize[, dst[, anchor[, normalize[, borderType]]]])
使用box filter滤波图像。
返回值
dst:方框滤波后得到的处理结果。
参数:
src:需要处理的图像。
ddepth:结果图的图像深度。一般使用 -1表示与原始图像使用相同的图像深度。
ksize: kernel的大小。如:(3,3),表示所取邻域为3x3.
anchor: 锚点。默认值是(-1, -1),表示当前计算像素值的点,位于kernel的中心点位置。
normalize: 是否进行归一化。
若参数为1.则进行归一化。即用邻域像素值之和除以邻域面积。
若参数为0. 则不进行归一化。则像素值使用邻域像素值之和。
borderType:边界式样。
#方框滤波 img = cv2.imread('images/ab.jpeg', cv2.IMREAD_COLOR) kernel_size = (3,3) img_box_nor = cv2.boxFilter(img, -1, kernel_size, normalize=1) img_box = cv2.boxFilter(img, -1, kernel_size, normalize=0) cv2.imshow("Norm", img_box_nor) cv2.imshow("No", img_box) cv2.waitKey(0) cv2.destroyAllWindows()
如果不选择归一化,则大部分区域超过uint8阈值,会到大上限,显示白色。
3. 高斯滤波:
在进行均值滤波和方框滤波时,其邻域的每个像素的权重是相同的。而在高斯滤波中,会将中心点附近的权重加大,远离中心点的权重则减小。
kernel 的形态可以如下:
计算过程则如下:
每个像素点的像素值,都由其本身和邻域内的其他像素值经过加权平均后得到。
高斯滤波中的kernel, 长宽可以不同,但必须是奇数。例如:
dst = cv.GaussianBlur(src, ksize, sigmaX[, dst[, sigmaY[, borderType]]])
dst: 高斯滤波后的结果。
src:原始图像。
ksize:滤波核大小。例如:(5,5)
sigmaX: 卷积核在水平方向上的标准差,用它来控制权重比例。
sigmaY: 卷积核在竖直方向上的标准差。若为0. 则采用sigmaX的值。 若sigmaX,sigmaY都为0. 则计算得到。 sigmaX=0.3x[(ksize.width-1)x0.5-1] +0.8 sigmaY=0.3x[(ksize.height-1)x0.5-1] +0.8
高斯滤波模板中最重要的参数就是高斯分布的标准差σ。它代表着数据的离散程度,如果σ较小,那么生成的模板中心系数越大,而周围的系数越小,这样对图像的平滑效果就不是很明显;相反,σ较大时,则生成的模板的各个系数相差就不是很大,比较类似于均值模板,对图像的平滑效果就比较明显。(标准差,见附1)
核大小固定,sigma值越大,权值分布越平缓。因此邻域各点值对输出值的影响越大,最终结果造成图像越模糊
核大小固定,sigma值越小,权值分布越突起。因此邻域各点值对输出值的影响越小,图像变化越小。假如中心点权值为1,其他点权值为0,最终结果是图像没有任何变化。
sigma固定时,核越大图像越模糊
sigma固定时,核越小图像变化越小
#高斯滤波 kernel_size = (11,11) img = cv2.imread("images/ab.jpeg", cv2.IMREAD_COLOR) gaussian_0 = cv2.GaussianBlur(img, kernel_size, 0, sigmaY=0) gaussian_2 = cv2.GaussianBlur(img, kernel_size, sigmaX=0.8) gaussian_5 = cv2.GaussianBlur(img, kernel_size, sigmaX=5) cv2.imshow("Image",img) cv2.imshow("gaussian_0", gaussian_0) cv2.imshow("gaussian_2", gaussian_2) cv2.imshow("gaussian_5", gaussian_5) cv2.waitKey(0) cv2.destroyAllWindows()
可以看到,标准差小,图像变化更小。
4. 中值滤波:
中值滤波与前面几种滤波方式不同。不再采用求平均值,求加权平均值等方式计算出滤波结果。它用邻域红所有元素的中间值来代替当前像素的像素值。
dst = cv.medianBlur(src, ksize[, dst])
ksize:长宽必须是1大的奇数。
5. 双边滤波:
双边滤波是综合考虑空间信息和色彩信息的滤波方式。之前的滤波方式,只考虑了空间信息,并在此基础上设置了权重。但没有考虑色彩信息。
dst =
cv.bilateralFilter( | src, d, sigmaColor, sigmaSpace[, dst[, borderType]] | ) |
6. 自定义滤波(2D卷积):
前述滤波方法中,一些可以设置卷积核大小,一些可以设置卷积核权重方差。但若想指用指定数值的卷积核。就需要用到2D卷积了。
dst = cv.filter2D( | src, ddepth, kernel[, dst[, anchor[, delta[, borderType]]]] | ) |
dst: 卷积后的结果。
src:原始图片。
ddepth:结果图像的的深度。若使用-1. 则和原图保持一致。
kernel: 卷积核。
附1:标准差:
是离均差平方的算术平均数(即:方差)的算术平方根,用σ表示。标准差也被称为标准偏差,或者实验标准差,在概率统计中最常使用作为统计分布程度上的测量依据
标准差定义是总体各单位标准值与其平均数离差平方的算术平均数的平方根。它反映组内个体间的离散程度。一个较大的标准差,代表大部分数值和其平均值之间差异较大;一个较小的标准差,代表这些数值较接近平均值。