标题
- 统计排序滤波器
- 中值、最大值、最小值、中点 滤波器
- 修正阿尔法均值滤波器
统计排序滤波器
中值、最大值、最小值、中点 滤波器
f^(x,y)=median{g(r,c)}(5.27)\hat{f}(x, y) = \text{median} \{g(r,c)\} \tag{5.27}f^(x,y)=median{g(r,c)}(5.27)
f^(x,y))=max{g(r,c)}(5.28)\hat{f}(x, y)) = \text{max} \{g(r,c)\} \tag{5.28}f^(x,y))=max{g(r,c)}(5.28)
f^(x,y)=min{g(r,c)}(5.29)\hat{f}(x, y) = \text{min} \{g(r,c)\} \tag{5.29}f^(x,y)=min{g(r,c)}(5.29)
f^(x,y)=12[max{g(r,c)}+min{g(r,c)}](5.30)\hat{f}(x, y) = \frac{1}{2}\big[\text{max}\{g(r,c)\} + \text{min}\{g(r,c)\} \big] \tag{5.30}f^(x,y)=21[max{g(r,c)}+min{g(r,c)}](5.30)
中值滤波器应用广泛,因为与大小相同的线性平滑滤波器相比,它能有效地降低某些随机噪声,且模糊度要小得多。对于单极和双极冲激噪声,中值滤波器的效果更好,但多次使用中值滤波器会使用图像模糊。
最大值滤波器可用于找到图像中的最亮点,或用于消弱与明亮区域相信的暗色区域。此外由于胡椒噪声的值很低,因此可用这种滤波器来降低胡椒噪声。
最小值滤波器用于找到图像中的最暗点,或用于削弱与暗色区域的明亮区域。此外,还可通过最小运算降低盐粒噪声。
中点滤波器是统计排序滤波器与平均滤波器的结合。它最适合于处理随机分布的噪声,如高斯噪声或均匀噪声。
修正阿尔法均值滤波器
f^(x,y)=1mn−d∑g(r,c)(5.31)\hat{f}(x, y) = \frac{1}{mn - d} \sum g(r,c) \tag{5.31}f^(x,y)=mn−d1∑g(r,c)(5.31)
d的取值范围是从0到mn−10到mn - 10到mn−1。 当d=0d=0d=0时,简化为算术平均滤波器。当d=mn−1d=mn-1d=mn−1,那么为中值滤波器。ddd取其它值时,修正阿尔法滤波器适合于处理多种混合噪声,如高斯噪声和椒盐噪声。
使用时需要选取合适的ddd值,才能得到比较好的结果,不同的值差别也很大。
# 中值、最大值、最小值、中点 滤波器
def median_filter(image, kernel):"""median filter, math: $$\hat{f}(x, y) = \text{median} \{g(r,c)\}$$param: image: input image for denoisingparam: kernel: input kernel, actually only use kernel shape, just want to keep the format as mean filterreturn: image after median filter"""height, width = image.shape[:2]m, n = kernel.shape[:2]padding_h = int((m -1)/2)padding_w = int((n -1)/2)# 这样的填充方式,可以奇数核或者偶数核都能正确填充image_pad = np.pad(image, ((padding_h, m - 1 - padding_h), \(padding_w, n - 1 - padding_w)), mode="edge")image_result = np.zeros(image.shape)for i in range(height):for j in range(width):temp = image_pad[i:i + m, j:j + n]image_result[i, j] = np.median(temp)return image_resultdef max_filter(image, kernel):"""max filter, math: $$\hat{f}(x, y)) = \text{max} \{g(r,c)\}$$param: image: input image for denoisingparam: kernel: input kernel, actually only use kernel shape, just want to keep the format as mean filterreturn: image after max filter"""height, width = image.shape[:2]m, n = kernel.shape[:2]padding_h = int((m -1)/2)padding_w = int((n -1)/2)# 这样的填充方式,可以奇数核或者偶数核都能正确填充image_pad = np.pad(image, ((padding_h, m - 1 - padding_h), \(padding_w, n - 1 - padding_w)), mode="constant", constant_values=0)img_result = np.zeros(image.shape)for i in range(height):for j in range(width):temp = image_pad[i:i + m, j:j + n]img_result[i, j] = np.max(temp)return img_resultdef min_filter(image, kernel):"""min filter, math: $$\hat{f}(x, y) = \text{min} \{g(r,c)\}$$param: image: input image for denoisingparam: kernel: input kernel, actually only use kernel shape, just want to keep the format as mean filterreturn: image after min filter"""height, width = image.shape[:2]m, n = kernel.shape[:2]padding_h = int((m -1)/2)padding_w = int((n -1)/2)# 这样的填充方式,可以奇数核或者偶数核都能正确填充image_pad = np.pad(image, ((padding_h, m - 1 - padding_h), \(padding_w, n - 1 - padding_w)), mode="edge", )img_result = np.zeros(image.shape)for i in range(height):for j in range(width):temp = image_pad[i:i + m, j:j + n]img_result[i, j] = np.min(temp)return img_resultdef middle_filter(image, kernel):"""middle filter, math: $$\hat{f}(x, y) = \frac{1}{2}\big[\text{max}\{g(r,c)\} + \text{min}\{g(r,c)\} \big]$$param: image: input image for denoisingparam: kernel: input kernel, actually only use kernel shape, just want to keep the format as mean filterreturn: image after middle filter"""height, width = image.shape[:2]m, n = kernel.shape[:2]padding_h = int((m -1)/2)padding_w = int((n -1)/2)# 这样的填充方式,可以奇数核或者偶数核都能正确填充image_pad = np.pad(image, ((padding_h, m - 1 - padding_h), \(padding_w, n - 1 - padding_w)), mode="edge")img_result = np.zeros(image.shape)for i in range(height):for j in range(width):temp = image_pad[i:i + m, j:j + n]img_result[i, j] = int(temp.max()/2 + temp.min()/2)return img_result
# 中值、最大值、最小值、中点 滤波器处理胡椒噪声
img_ori = cv2.imread('DIP_Figures/DIP3E_Original_Images_CH05/Fig0508(a)(circuit-board-pepper-prob-pt1).tif', 0) #直接读为灰度图像kernel = np.ones([3, 3])
img_median = median_filter(img_ori, kernel=kernel)
img_max = max_filter(img_ori, kernel=kernel)
img_min = min_filter(img_ori, kernel=kernel)
img_middle = middle_filter(img_ori, kernel=kernel)plt.figure(figsize=(15, 10))plt.subplot(231), plt.imshow(img_ori, 'gray'), plt.title('Original'), plt.xticks([]), plt.yticks([])
plt.subplot(232), plt.imshow(img_median, 'gray'), plt.title('Median filter'), plt.xticks([]), plt.yticks([])
plt.subplot(233), plt.imshow(img_max, 'gray'), plt.title('Max filter'), plt.xticks([]), plt.yticks([])
plt.subplot(234), plt.imshow(img_min, 'gray'), plt.title('Min filter'), plt.xticks([]), plt.yticks([])
plt.subplot(235), plt.imshow(img_middle, 'gray'), plt.title('Middle filter'), plt.xticks([]), plt.yticks([])
plt.tight_layout()
plt.show()
# 中值、最大值、最小值、中点 滤波器处理盐粒噪声
img_ori = cv2.imread('DIP_Figures/DIP3E_Original_Images_CH05/Fig0508(b)(circuit-board-salt-prob-pt1).tif', 0) #直接读为灰度图像kernel = np.ones([3, 3])
img_median = median_filter(img_ori, kernel=kernel)
img_max = max_filter(img_ori, kernel=kernel)
img_min = min_filter(img_ori, kernel=kernel)
img_middle = middle_filter(img_ori, kernel=kernel)plt.figure(figsize=(15, 10))plt.subplot(231), plt.imshow(img_ori, 'gray'), plt.title('Original'), plt.xticks([]), plt.yticks([])
plt.subplot(232), plt.imshow(img_median, 'gray'), plt.title('Median filter'), plt.xticks([]), plt.yticks([])
plt.subplot(233), plt.imshow(img_max, 'gray'), plt.title('Max filter'), plt.xticks([]), plt.yticks([])
plt.subplot(234), plt.imshow(img_min, 'gray'), plt.title('Min filter'), plt.xticks([]), plt.yticks([])
plt.subplot(235), plt.imshow(img_middle, 'gray'), plt.title('Middle filter'), plt.xticks([]), plt.yticks([])
plt.tight_layout()
plt.show()
# 中值、最大值、最小值、中点 滤波器处理高斯噪声
img_ori = cv2.imread('DIP_Figures/DIP3E_Original_Images_CH05/Fig0507(b)(ckt-board-gauss-var-400).tif', 0) #直接读为灰度图像kernel = np.ones([3, 3])
img_median = median_filter(img_ori, kernel=kernel)
img_max = max_filter(img_ori, kernel=kernel)
img_min = min_filter(img_ori, kernel=kernel)
img_middle = middle_filter(img_ori, kernel=kernel)plt.figure(figsize=(15, 10))plt.subplot(231), plt.imshow(img_ori, 'gray'), plt.title('Original'), plt.xticks([]), plt.yticks([])
plt.subplot(232), plt.imshow(img_median, 'gray'), plt.title('Median filter'), plt.xticks([]), plt.yticks([])
plt.subplot(233), plt.imshow(img_max, 'gray'), plt.title('Max filter'), plt.xticks([]), plt.yticks([])
plt.subplot(234), plt.imshow(img_min, 'gray'), plt.title('Min filter'), plt.xticks([]), plt.yticks([])
plt.subplot(235), plt.imshow(img_middle, 'gray'), plt.title('Middle filter'), plt.xticks([]), plt.yticks([])
plt.tight_layout()
plt.show()
# 多次中值滤波器处理椒盐噪声
img_ori = cv2.imread('DIP_Figures/DIP3E_Original_Images_CH05/Fig0507(a)(ckt-board-orig).tif', 0) #直接读为灰度图像img_salt_pepper = add_salt_pepper(img_ori, ps=0.1, pp=0.1)kernel = np.ones([3, 3])
img_median_1 = median_filter(img_salt_pepper, kernel=kernel)
img_median_2 = median_filter(img_median_1, kernel=kernel)
img_median_3 = median_filter(img_median_2, kernel=kernel)plt.figure(figsize=(15, 10))
plt.subplot(231), plt.imshow(img_ori, 'gray'), plt.title('Original'), plt.xticks([]), plt.yticks([])
plt.subplot(232), plt.imshow(img_salt_pepper, 'gray'), plt.title('With salt pepper 0.1'), plt.xticks([]), plt.yticks([])
plt.subplot(233), plt.imshow(img_median_1, 'gray'), plt.title('1 time Median filter'), plt.xticks([]), plt.yticks([])
plt.subplot(234), plt.imshow(img_median_2, 'gray'), plt.title('2 times Median filter'), plt.xticks([]), plt.yticks([])
plt.subplot(235), plt.imshow(img_median_3, 'gray'), plt.title('3 times Median filter'), plt.xticks([]), plt.yticks([])
plt.tight_layout()
plt.show()
def modified_alpha_mean(image, kernel, d=0):"""modified alpha filter, math: $$$$\hat{f}(x, y) = \frac{1}{mn - d} \sum g(r,c)$$param: image: input image for denoisingparam: kernel: input kernel, actually only use kernel shape, just want to keep the format as mean filterparam: d : input int, which is from 0 to m * nreturn: image after modified alpha filter"""height, width = image.shape[:2]m, n = kernel.shape[:2]padding_h = int((m -1)/2)padding_w = int((n -1)/2)# 这样的填充方式,可以奇数核或者偶数核都能正确填充image_pad = np.pad(image, ((padding_h, m - 1 - padding_h), \(padding_w, n - 1 - padding_w)), mode="edge")img_result = np.zeros(image.shape)for i in range(height):for j in range(width):temp = np.sum(image_pad[i:i + m, j:j + n] * 1)img_result[i, j] = temp / (m * n - d)return img_result
# 修正阿尔法滤波器处理高斯噪声
img_ori = cv2.imread('DIP_Figures/DIP3E_Original_Images_CH05/Fig0507(b)(ckt-board-gauss-var-400).tif', 0) #直接读为灰度图像kernel = np.ones([3, 3])img_median = median_filter(img_ori, kernel=kernel)
img_max = max_filter(img_ori, kernel=kernel)
img_min = min_filter(img_ori, kernel=kernel)
img_alpha_d_1 = modified_alpha_mean(img_ori, kernel, d=1)
img_alpha_d_05 = modified_alpha_mean(img_ori, kernel, d=0.5)plt.figure(figsize=(15, 10))
plt.subplot(231), plt.imshow(img_ori, 'gray'), plt.title('Original'), plt.xticks([]), plt.yticks([])
plt.subplot(232), plt.imshow(img_median, 'gray'), plt.title('Median filter'), plt.xticks([]), plt.yticks([])
plt.subplot(233), plt.imshow(img_max, 'gray'), plt.title('Max filter'), plt.xticks([]), plt.yticks([])
plt.subplot(234), plt.imshow(img_min, 'gray'), plt.title('Min filter'), plt.xticks([]), plt.yticks([])
plt.subplot(235), plt.imshow(img_alpha_d_1, 'gray'), plt.title('Modified alpha d=1'), plt.xticks([]), plt.yticks([])
plt.subplot(236), plt.imshow(img_alpha_d_05, 'gray'), plt.title('Modified alpha d=0.5'), plt.xticks([]), plt.yticks([])
plt.tight_layout()
plt.show()
# 修正阿尔法滤波器处理高斯噪声+椒盐噪声
img_ori = cv2.imread('DIP_Figures/DIP3E_Original_Images_CH05/Fig0507(a)(ckt-board-orig).tif', 0) #直接读为灰度图像img_uniform = cv2.imread('DIP_Figures/DIP3E_Original_Images_CH05/Fig0512(a)(ckt-uniform-var-800).tif', 0)
img_salt_pepper = cv2.imread('DIP_Figures/DIP3E_Original_Images_CH05/Fig0512(b)(ckt-uniform-plus-saltpepr-prob-pt1).tif', 0) kernel = np.ones([5, 5])img_geometric_mean = geometric_mean(img_salt_pepper, kernel=kernel)
img_dst = img_salt_pepper - img_geometric_mean
img_median = median_filter(img_salt_pepper, kernel=kernel)
img_modified_alpha = modified_alpha_mean(img_salt_pepper, kernel=kernel, d=1)plt.figure(figsize=(15, 10))plt.subplot(231), plt.imshow(img_ori, 'gray'), plt.title('Original'), plt.xticks([]),plt.yticks([])
plt.subplot(232), plt.imshow(img_uniform, 'gray'), plt.title('Uniform noise'), plt.xticks([]),plt.yticks([])
plt.subplot(233), plt.imshow(img_salt_pepper, 'gray'), plt.title('Uniform plus salt pepper'), plt.xticks([]),plt.yticks([])
plt.subplot(234), plt.imshow(img_dst, 'gray'), plt.title('Geometric mean'), plt.xticks([]),plt.yticks([])
plt.subplot(235), plt.imshow(img_median, 'gray'), plt.title('1 time Median filter'), plt.xticks([]),plt.yticks([])
plt.subplot(236), plt.imshow(img_modified_alpha, 'gray'), plt.title('Modified alpha mean d=6'), plt.xticks([]),plt.yticks([])
plt.tight_layout()
plt.show()