空域滤波增强
空域滤波增强也称为模板操作,主要以像素邻域为基础对图像进行增强,增强函数E()定义在像素点(x,y)的某个邻域上。模板是指滤波器、核、掩模或窗口。邻域可以是任意形状,通常采用正方形或矩形阵列。
空域滤波增强的基本原理是利用图像与模板的卷积来进行。模板通常取尺寸为n×n的小图像,n一般为奇数,此时,模板的半径定义为:r=(n-1)/2。
空域滤波增强可分为以下4类
(1)线性平滑滤波器
(2)非线性平滑滤波器
(3)线性锐化滤波器
(4)非线性锐化滤波器
均值滤波
均值滤波器使用网格内像素的平均值。
def mean_filter(img, K_size=3):
H, W, C = img.shape
# zero padding
pad = K_size // 2
out = np.zeros((H + pad * 2, W + pad * 2, C), dtype=np.float)
out[pad: pad + H, pad: pad + W] = img.copy().astype(np.float)
tmp = out.copy()
# filtering
for y in range(H):
for x in range(W):
for c in range(C):
out[pad + y, pad + x, c] = np.mean(tmp[y: y + K_size, x: x + K_size, c])
out = out[pad: pad + H, pad: pad + W].astype(np.uint8)
return out
中值滤波
将网格内像素数据按大小顺序排列,处于中心位置的那个数作为处理结果
def median_filter(img, K_size=3):
H, W, C = img.shape
# zero padding
pad = K_size // 2
out = np.zeros((H + pad * 2, W + pad * 2, C), dtype=np.float)
out[pad: pad + H, pad: pad + W] = img.copy().astype(np.float)
tmp = out.copy()
# filtering
for y in range(H):
for x in range(W):
for c in range(C):
out[pad + y, pad + x, c] = np.median(tmp[y: y + K_size, x: x + K_size, c])
out = out[pad: pad + H, pad: pad + W].astype(np.uint8)
return out
差分滤波器
差分滤波器对图像亮度急剧变化的边缘有提取效果,可以获得邻接像素的差值。
def different_filter(img, K_size=3):
H, W = img.shape
# Zero padding
pad = K_size // 2
out = np.zeros((H + pad * 2, W + pad * 2), dtype=np.float)
out[pad: pad + H, pad: pad + W] = img.copy().astype(np.float)
tmp = out.copy()
out_v = out.copy()
out_h = out.copy()
# vertical kernel
Kv = [[0., -1., 0.],[0., 1., 0.],[0., 0., 0.]]
# horizontal kernel
Kh = [[0., 0., 0.],[-1., 1., 0.], [0., 0., 0.]]
# filtering
for y in range(H):
for x in range(W):
out_v[pad + y, pad + x] = np.sum(Kv * (tmp[y: y + K_size, x: x + K_size]))
out_h[pad + y, pad + x] = np.sum(Kh * (tmp[y: y + K_size, x: x + K_size]))
out_v = np.clip(out_v, 0, 255)
out_h = np.clip(out_h, 0, 255)
out_v = out_v[pad: pad + H, pad: pad + W].astype(np.uint8)
out_h = out_h[pad: pad + H, pad: pad + W].astype(np.uint8)
return out_v, out_h
Sobel滤波器
Sobel滤波器可以提取特定方向(纵向或横向)的边缘
def sobel_filter(img, K_size=3):
# if len(img.shape) == 3:
# H, W, C = img.shape
# else:
# img = np.expand_dims(img, axis=-1)
# H, W, C = img.shape
H, W = img.shape
# Zero padding
pad = K_size // 2
out = np.zeros((H + pad * 2, W + pad * 2), dtype=np.float)
out[pad: pad + H, pad: pad + W] = img.copy().astype(np.float)
tmp = out.copy()
out_v = out.copy()
out_h = out.copy()
## Sobel vertical
Kv = [[1., 2., 1.],[0., 0., 0.], [-1., -2., -1.]]
## Sobel horizontal
Kh = [[1., 0., -1.],[2., 0., -2.],[1., 0., -1.]]
# filtering
for y in range(H):
for x in range(W):
out_v[pad + y, pad + x] = np.sum(Kv * (tmp[y: y + K_size, x: x + K_size]))
out_h[pad + y, pad + x] = np.sum(Kh * (tmp[y: y + K_size, x: x + K_size]))
out_v = np.clip(out_v, 0, 255)
out_h = np.clip(out_h, 0, 255)
out_v = out_v[pad: pad + H, pad: pad + W].astype(np.uint8)
out_h = out_h[pad: pad + H, pad: pad + W].astype(np.uint8)
return out_v, out_h