1.中值濾波器
中值濾波器屬於非線性濾波器,中值濾波是對整幅圖像求解中位數的過程。具體實現時用一個模板掃描圖像中的每一個像素,然后用模板范圍內所有像素的中位數像素代替原來模板中心的像素。例如下圖中圖像中間150灰度的像素在中值濾波后灰度將會賦值為124.
中值濾波器現起來比較容易,可以調用opencv-python中的庫函數也可以自己編寫相關函數,中值濾波器相關函數主體如下
import cv2 as cv import matplotlib.pyplot as plt import math import numpy as np def get_median(data): data.sort() half = len(data) // 2 return data[half] # 計算灰度圖像的中值濾波 def my_median_blur_gray(image, size): data = [] sizepart = int(size/2) for i in range(image.shape[0]): for j in range(image.shape[1]): for ii in range(size): for jj in range(size): # 首先判斷所以是否超出范圍,也可以事先對圖像進行零填充 if (i+ii-sizepart)<0 or (i+ii-sizepart)>=image.shape[0]: pass elif (j+jj-sizepart)<0 or (j+jj-sizepart)>=image.shape[1]: pass else: data.append(image[i+ii-sizepart][j+jj-sizepart]) # 取每個區域內的中位數 image[i][j] = int(get_median(data)) data=[] return image # 計算彩色圖像的中值濾波 def my_median_blur_RGB(image, size): (b ,r, g) = cv.split(image) blur_b = my_median_blur_gray(b, size) blur_r = my_median_blur_gray(r, size) blur_g = my_median_blur_gray(g, size) result = cv.merge((blur_b, blur_r, blur_g)) return result if __name__ == '__main__': image_test1 = cv.imread('test1.pgm') # 調用自定義函數 my_image_blur_median = my_median_blur_RGB(image_test1, 5) # 調用庫函數 computer_image_blur_median = cv.medianBlur(image_test1, 5) fig = plt.figure() fig.add_subplot(131) plt.title('original') plt.imshow(image_test1) fig.add_subplot(132) plt.title('my median') plt.imshow(my_image_blur_median) fig.add_subplot(133) plt.title('library median') plt.imshow(computer_image_blur_median) plt.show()
中值濾波器濾波效果為
2.高斯濾波器
高斯濾波是一種線性平滑濾波,和均值濾波計算方法相似,但是其模板中心像素的權重要大於鄰接像素的權重。具體的數值比例關系按照下面的二元高斯函數進行計算。
比如要產生一個下圖3×3的模板,可以將模板中像素坐標帶入高斯函數中得到關於σ的模板矩陣。
若去σ值為0.85,計算矩陣個元素數值,再將左上角的數值歸一化的矩陣為
將此矩陣取整即可得到圖像處理的一個模板
當然,去σ為不同的數值可以得到不同的模板。高斯濾波可以有效地去除高斯噪聲,由於很多圖片都具有高斯噪聲,所以高斯濾波在圖像圖例上用得很廣。
高斯濾波器自定義函數主體為
import cv2 as cv import matplotlib.pyplot as plt import math import numpy as np # 高斯濾波函數 def my_function_gaussion(x, y, sigma): return math.exp(-(x**2 + y**2) / (2*sigma**2)) / (2*math.pi*sigma**2) # 產生高斯濾波矩陣 def my_get_gaussion_blur_retric(size, sigma): n = size // 2 blur_retric = np.zeros([size, size]) # 根據尺寸和sigma值計算高斯矩陣 for i in range(size): for j in range(size): blur_retric[i][j] = my_function_gaussion(i-n, j-n, sigma) # 將高斯矩陣歸一化 blur_retric = blur_retric / blur_retric[0][0] # 將高斯矩陣轉換為整數 blur_retric = blur_retric.astype(np.uint32) # 返回高斯矩陣 return blur_retric # 計算灰度圖像的高斯濾波 def my_gaussion_blur_gray(image, size, sigma): blur_retric = my_get_gaussion_blur_retric(size, sigma) n = blur_retric.sum() sizepart = size // 2 data = 0 # 計算每個像素點在經過高斯模板變換后的值 for i in range(image.shape[0]): for j in range(image.shape[1]): for ii in range(size): for jj in range(size): # 條件語句為判斷模板對應的值是否超出邊界 if (i+ii-sizepart)<0 or (i+ii-sizepart)>=image.shape[0]: pass elif (j+jj-sizepart)<0 or (j+jj-sizepart)>=image.shape[1]: pass else: data += image[i+ii-sizepart][j+jj-sizepart] * blur_retric[ii][jj] image[i][j] = data / n data = 0 # 返回變換后的圖像矩陣 return image # 計算彩色圖像的高斯濾波 def my_gaussion_blur_RGB(image, size, sigma): (b ,r, g) = cv.split(image) blur_b = my_gaussion_blur_gray(b, size, sigma) blur_r = my_gaussion_blur_gray(r, size, sigma) blur_g = my_gaussion_blur_gray(g, size, sigma) result = cv.merge((blur_b, blur_r, blur_g)) return result if __name__ == '__main__': image_test1 = cv.imread('test1.pgm') # 進行高斯濾波器比較 my_image_blur_gaussion = my.my_gaussion_blur_RGB(image_test1, 5, 0.8) computer_image_blur_gaussion = cv.GaussianBlur(image_test1, (5, 5), 0.8) fig = plt.figure() fig.add_subplot(131) plt.title('original') plt.imshow(image_test1) fig.add_subplot(132) plt.title('my gaussion') plt.imshow(my_image_blur_gaussion) fig.add_subplot(133) plt.title('library gaussion') plt.imshow(computer_image_blur_gaussion) plt.show()
5×5高斯濾波器濾波效果為