概述
线性滤波:方框滤波、均值滤波、高斯滤波
非线性滤波: 最大最小值滤波、中值滤波、双边滤波
高通滤波:去掉低频信号,留下高频信号。留下图像边界。
低通滤波:去掉高频信号,留下低频信号。去噪,模糊图像。
均值滤波
一种低通线性滤波器,可以用来消除图像尖锐噪声,实现图像平滑、模糊。
opencv代码:
cv2.blur(img, (5, 5))
python代码实现:
def blur(img, size):
mask = np.ones((size, size))/ size / size
pad = size // 2
h, w = img.shape
new_img = np.zeros([h, w])
img = np.pad(img, (pad, pad), 'constant')
for i in range(h):
for j in range(w):
new_img[i, j] = np.sum(img[i:i + size, j:j + size] * mask)
return np.uint8(new_img)
方框滤波
和均值滤波没有本质差别。
#参数:原始图像,目标图像深度,核大小,normalize属性(是否对目标图像进行归一化处理)
#normalize为true时与均值滤波一样
#normalize为true时表示对加和后的结果不进行平均操作,大于255的使用255表示
img = cv2.boxFilter(img, -1, (5,5), normalize=True)
高斯滤波
一种低通滤波器、线性平滑滤波,用于消除高斯噪声(服从正态分布的噪声)。
操作方法:用一个模板扫描图像中的每一个像素,用模板确定的邻域内像素的加权平均灰度值去替代模板中心像素点的值。
opencv代码:
#(5, 5)表示高斯核大小是5,标准差取0
cv2.GaussianBlur(img,(5,5),0)
python代码实现:
def gaussian(img, kernel=5, sigma=1.5):
filter = np.zeros([kernel, kernel])
pad = kernel//2
for i in range(-pad, -pad + kernel):
for j in range(-pad, -pad + kernel):
filter[i,j] = np.exp( - (i ** 2 + j ** 2) / (2 * sigma * sigma))/(2 * np.pi * sigma * sigma)
filter/=filter.sum()
#与图像卷积
h, w = img.shape
new_img = np.zeros([h, w])
img = np.pad(img, (pad,pad), 'constant')
for i in range(h):
for j in range(w):
new_img[i, j] = np.sum(img[i:i + kernel, j:j + kernel] * filter)
return new_img
中值滤波
一种非线性滤波器,通过对邻域内像素按灰度排序,将中间值代替中心点的像素值。
中值滤波对于滤除脉冲干扰及消除椒盐噪声最有效,
opencv代码:
cv2.medianBlur(img, 5)
python代码实现:
pad = size // 2
h, w = img.shape
new_img = np.zeros([h, w])
img = np.pad(img, (pad, pad), 'constant')
for i in range(h):
for j in range(w):
new_img[i, j] = np.median(img[i:i + size, j:j + size])
双边滤波
一种非线性滤波器,它是一种边缘保护滤波方法,作用是保持边缘、降噪平滑。
双边滤波同时考虑了像素的空间差异(高斯加权,高斯滤波只关注了位置对中心像素的影响)和像素的强度差异(像素值越相近,权重越大)。
双边滤波就是在高斯滤波的基础上加入了像素值的权重。
opencv代码:
# 9是邻域直径,两个75分别是空间高斯函数标准差,灰度值相似性高斯函数标准差
cv2.bilateralFilter(img, 9, 75, 75)
python代码实现:
def distance(x, y,i, j):
return np.sqrt((x - i) ** 2 + (y - j) ** 2)
def gaussian(x, sigma):
return (1 / (2 * np.pi * (sigma ** 2))) * np.exp(-(x ** 2) / (2 * (sigma ** 2)))
h, w = img.shape
new_img = np.zeros([h, w])
for i in range(h):
for j in range(w):
value = 0
weight = 0
for ri in range(-radius, radius + 1):
for ci in range(-radius, radius + 1):
y = i + ri
x = j + ci
if y < 0 or x < 0 or y >= h or x >= w:
continue
gauss_space = gaussian(distance(i,j,y,x), sigmaSpace)
gauss_color = gaussian(abs(img[i,j]-img[y,x]), sigmaColor)
we = gauss_space * gauss_color
value += we * img[y, x]
weight += we
value /= weight
new_img[i,j] = value