【OpenCV 例程 300 篇】101. 自适应中值滤波器
自适应中值滤波器根据预先设定的条件,在滤波的过程中动态改变滤波器的窗口尺寸大小;进一步地,根据条件判断当前像素是否噪声,由此决定是否用邻域中值替换当前像素。自适应中值滤波器可以处理较大概率的脉冲噪声,平滑非脉冲噪声,尽可能保护图像细节信息,避免图像边缘的细化或者粗化。......
专栏地址:『youcans 的 OpenCV 例程 300篇 - 总目录』
【第 7 章:图像复原与重建】
100. 自适应局部降噪滤波器
101. 自适应中值滤波器
102. 陷波带阻滤波器的传递函数
【youcans 的 OpenCV 例程 300 篇】101. 自适应中值滤波器
3.8 自适应中值滤波器(Adaptive median filter)
中值滤波器的窗口尺寸是固定大小不变的,不能同时兼顾去噪和保护图像的细节,在噪声的密度较小时的性能较好,当噪声概率较高时的性能就会劣化。
自适应中值滤波器根据预先设定的条件,在滤波的过程中动态改变滤波器的窗口尺寸大小;进一步地,根据条件判断当前像素是否噪声,由此决定是否用邻域中值替换当前像素。
自适应中值滤波器可以处理较大概率的脉冲噪声,平滑非脉冲噪声,尽可能保护图像细节信息,避免图像边缘的细化或者粗化。
令 S x y Sxy Sxy 表示中心在点 ( x , y ) (x,y) (x,y) 、大小为 m ∗ n m*n m∗n 的矩形子窗口(邻域),滤波器在由 S x y Sxy Sxy 定义的邻域操作。
Z m i n 、 Z m a x 、 Z m e d Zmin、Zmax、Zmed Zmin、Zmax、Zmed 表示 S x y Sxy Sxy 中的最小灰度值、最大灰度值和灰度值的中值, Z x y Zxy Zxy 是点 ( x , y ) (x,y) (x,y) 的灰度值, S m a x Smax Smax 是允许的最大窗口尺寸。
自适应中值滤波器分为两个过程:
-
Step A:
- A1 = Zmed - Zmin
- A2 = Zmed - Zmax
- 如果 A1>0 且 A2<0,则跳转到 Step B;否则,增大窗口尺寸
- 如果增大后的尺寸 ≤ Smax,则重复 A;否则,输出 Zmed
-
Step B:
- B1 = Zxy - Zmin
- B2 = Zxy - Zmax
- 如果 B1>0 且 B2<0,则输出 Zxy;否则,输出 Zmed
StepA 的目的是确定当前窗口内得到的中值 Zmed 是否是噪声。如果 Zmin<Zmed<Zmax,则中值 Zmed 不是噪声,转到StepB。如果Zmin<Zxy<Zmax,则 Zxy 不是噪声,滤波器输出 Zxy。如果不满足上述条件,则判定 Zxy 是噪声,输出中值 Zmed。
如果在StepA中,Zmed 不满足条件 Zmin<Zmed<Zmax,则可判断得到的中值 Zmed 是噪声。这时要增大滤波器的窗口尺寸,在更大的范围内寻找一个非噪声点的中值。
因此,如果图像中噪声的概率较低,自适应中值滤波器可以使用较小的窗口尺寸,以提高计算速度;反之,如果噪声的概率较高,则需要增大滤波器的窗口尺寸,以改善滤波效果。
例程 9.15:自适应中值滤波器
# # 9.15: 自适应中值滤波器 (Adaptive median filter)
img = cv2.imread("../images/Fig0514a.tif", 0) # flags=0 读取为灰度图像
hImg = img.shape[0]
wImg = img.shape[1]
smax = 7 # 允许最大窗口尺寸
m, n = smax, smax
imgAriMean = cv2.boxFilter(img, -1, (m, n)) # 算术平均滤波
# 边缘填充
hPad = int((m-1) / 2)
wPad = int((n-1) / 2)
imgPad = np.pad(img.copy(), ((hPad, m-hPad-1), (wPad, n-wPad-1)), mode="edge")
imgMedianFilter = np.zeros(img.shape) # 中值滤波器
imgAdaMedFilter = np.zeros(img.shape) # 自适应中值滤波器
for i in range(hPad, hPad+hImg):
for j in range(wPad, wPad+wImg):
# 1. 中值滤波器 (Median filter)
ksize = 3
k = int(ksize/2)
pad = imgPad[i-k:i+k+1, j-k:j+k+1] # 邻域 Sxy, m*n
imgMedianFilter[i-hPad, j-wPad] = np.median(pad)
# 2. 自适应中值滤波器 (Adaptive median filter)
ksize = 3
k = int(ksize/2)
pad = imgPad[i-k:i+k+1, j-k:j+k+1]
zxy = img[i-hPad][j-wPad]
zmin = np.min(pad)
zmed = np.median(pad)
zmax = np.max(pad)
if zmin < zmed < zmax:
if zmin < zxy < zmax:
imgAdaMedFilter[i-hPad, j-wPad] = zxy
else:
imgAdaMedFilter[i-hPad, j-wPad] = zmed
else:
while True:
ksize = ksize + 2
if zmin < zmed < zmax or ksize > smax:
break
k = int(ksize / 2)
pad = imgPad[i-k:i+k+1, j-k:j+k+1]
zmed = np.median(pad)
zmin = np.min(pad)
zmax = np.max(pad)
if zmin < zmed < zmax or ksize > smax:
if zmin < zxy < zmax:
imgAdaMedFilter[i-hPad, j-wPad] = zxy
else:
imgAdaMedFilter[i-hPad, j-wPad] = zmed
plt.figure(figsize=(9, 6))
plt.subplot(131), plt.axis('off'), plt.title("Original")
plt.imshow(img, cmap='gray', vmin=0, vmax=255)
plt.subplot(132), plt.axis('off'), plt.title("Median filter")
plt.imshow(imgMedianFilter, cmap='gray', vmin=0, vmax=255)
plt.subplot(133), plt.axis('off'), plt.title("Adaptive median filter")
plt.imshow(imgAdaMedFilter, cmap='gray', vmin=0, vmax=255)
plt.tight_layout()
plt.show()
(本节完)
版权声明:
youcans@xupt 原创作品,转载必须标注原文链接:(https://blog.csdn.net/youcans/article/details/122839526)
Copyright 2022 youcans, XUPT
Crated:2022-2-1
更多推荐
所有评论(0)