標題
- 統計排序濾波器
- 中值、最大值、最小值、中點 濾波器
- 修正阿爾法均值濾波器
統計排序濾波器
中值、最大值、最小值、中點 濾波器
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()