影象濾波器演算法總結及程式碼實現
阿新 • • 發佈:2021-02-02
技術標籤:影象處理
影象濾波器演算法總結及程式碼實現
概述
線性濾波:方框濾波、均值濾波、高斯濾波
非線性濾波: 最大最小值濾波、中值濾波、雙邊濾波
高通濾波:去掉低頻訊號,留下高頻訊號。留下影象邊界。
低通濾波:去掉高頻訊號,留下低頻訊號。去噪,模糊影象。
均值濾波
一種低通線性濾波器,可以用來消除影象尖銳噪聲,實現影象平滑、模糊。
opencv程式碼:
cv2.blur(img, (5, 5))
python程式碼實現:
def blur(img, size):
mask = np.ones((size, size)) / size / size
pad = size // 2
h, w = img.shape
new_img = np.zeros([h, w])
img = np.pad(img, (pad, pad), 'constant')
for i in range(h):
for j in range(w):
new_img[i, j] = np.sum(img[i:i + size, j:j + size] * mask)
return np.uint8(new_img)
方框濾波
和均值濾波沒有本質差別。
#引數:原始影象, 目標影象深度,核大小,normalize屬性(是否對目標影象進行歸一化處理)
#normalize為true時與均值濾波一樣
#normalize為true時表示對加和後的結果不進行平均操作,大於255的使用255表示
img = cv2.boxFilter(img, -1, (5,5), normalize=True)
高斯濾波
一種低通濾波器、線性平滑濾波,用於消除高斯噪聲(服從正態分佈的噪聲)。
操作方法:用一個模板掃描影象中的每一個畫素,用模板確定的鄰域內畫素的加權平均灰度值去替代模板中心畫素點的值。
opencv程式碼:
#(5, 5)表示高斯核大小是5,標準差取0
cv2.GaussianBlur (img,(5,5),0)
python程式碼實現:
def gaussian(img, kernel=5, sigma=1.5):
filter = np.zeros([kernel, kernel])
pad = kernel//2
for i in range(-pad, -pad + kernel):
for j in range(-pad, -pad + kernel):
filter[i,j] = np.exp( - (i ** 2 + j ** 2) / (2 * sigma * sigma))/(2 * np.pi * sigma * sigma)
filter/=filter.sum()
#與影象卷積
h, w = img.shape
new_img = np.zeros([h, w])
img = np.pad(img, (pad,pad), 'constant')
for i in range(h):
for j in range(w):
new_img[i, j] = np.sum(img[i:i + kernel, j:j + kernel] * filter)
return new_img
中值濾波
一種非線性濾波器,通過對鄰域內畫素按灰度排序,將中間值代替中心點的畫素值。
中值濾波對於濾除脈衝干擾及消除椒鹽噪聲最有效,
opencv程式碼:
cv2.medianBlur(img, 5)
python程式碼實現:
pad = size // 2
h, w = img.shape
new_img = np.zeros([h, w])
img = np.pad(img, (pad, pad), 'constant')
for i in range(h):
for j in range(w):
new_img[i, j] = np.median(img[i:i + size, j:j + size])
雙邊濾波
一種非線性濾波器,它是一種邊緣保護濾波方法,作用是保持邊緣、降噪平滑。
雙邊濾波同時考慮了畫素的空間差異(高斯加權,高斯濾波只關注了位置對中心畫素的影響)和畫素的強度差異(畫素值越相近,權重越大)。
雙邊濾波就是在高斯濾波的基礎上加入了畫素值的權重。
opencv程式碼:
# 9是鄰域直徑,兩個75分別是空間高斯函式標準差,灰度值相似性高斯函式標準差
cv2.bilateralFilter(img, 9, 75, 75)
python程式碼實現:
def distance(x, y,i, j):
return np.sqrt((x - i) ** 2 + (y - j) ** 2)
def gaussian(x, sigma):
return (1 / (2 * np.pi * (sigma ** 2))) * np.exp(-(x ** 2) / (2 * (sigma ** 2)))
h, w = img.shape
new_img = np.zeros([h, w])
for i in range(h):
for j in range(w):
value = 0
weight = 0
for ri in range(-radius, radius + 1):
for ci in range(-radius, radius + 1):
y = i + ri
x = j + ci
if y < 0 or x < 0 or y >= h or x >= w:
continue
gauss_space = gaussian(distance(i,j,y,x), sigmaSpace)
gauss_color = gaussian(abs(img[i,j]-img[y,x]), sigmaColor)
we = gauss_space * gauss_color
value += we * img[y, x]
weight += we
value /= weight
new_img[i,j] = value