目錄:
- 1.濾波的相關(guān)概念
- 2.卷積操作
- 3.平滑操作(低通濾波)
- 均值濾波
- 中值濾波
- 高斯濾波
- 雙邊濾波
- 4.銳化操作(高通濾波)
- 自定義銳化核
- USM銳化(UnsharpMask)
- 5.梯度操作(高通濾波)
- Sobel算子
- Scharr算子
- Laplacian算子
一、濾波的概念
濾波是將信號(hào)中特定波段頻率濾除的操作,是抑制和防止干擾的一項(xiàng)重要措施。
圖像濾波是圖像預(yù)處理中不可缺少的操作,其處理效果的好壞將直接影響到后續(xù)圖像處理和分析的有效性和可靠性。圖像濾波,即在盡量保留圖像細(xì)節(jié)特征的條件下對(duì)目標(biāo)圖像的噪聲進(jìn)行抑制。圖像濾波的目的:
- 1.消除圖像中混入的噪聲;
- 2.為圖像識(shí)別抽取出圖像特征。
濾波可分為 低通濾波、高通濾波、中通濾波、阻帶濾波。
- 低通濾波/平滑濾波:減弱或阻隔高頻信號(hào),保留低頻信號(hào)??墒箞D像變模糊,主要用于去噪。
- 高通濾波:減弱或阻隔低頻信號(hào),保留高頻信號(hào)。一般用于獲取圖像邊緣、輪廓或梯度。
- 中通濾波:獲取已知頻率范圍內(nèi)的信號(hào)。
- 阻帶濾波:去掉已知頻率范圍內(nèi)的信號(hào)。
二、卷積操作
圖像的濾波操作一般用卷積操作來實(shí)現(xiàn),卷積核一般稱為濾波器。
卷積操作:圖像卷積可以看成是一個(gè)滑動(dòng)的窗口(卷積核)在一個(gè)比它大的圖像上有規(guī)則(從左向右,從上往下)地滑動(dòng),對(duì)每一次窗口覆蓋到的圖像子區(qū)域都會(huì)進(jìn)行點(diǎn)乘操作,并將得到的值作為原圖中被窗口覆蓋區(qū)域的中心像素點(diǎn)的新值。
與CNN里的卷積不同,經(jīng)典的卷積算子(即卷積核)往往是人們根據(jù)研究和經(jīng)驗(yàn)事先設(shè)定好的特征提取算子,而CNN里的卷積核是通過訓(xùn)練不斷調(diào)整最終得到合適的權(quán)值參數(shù)。
函數(shù):
1.卷積操作
filter2D(src, ddepth, kernel, dst=None, anchor=None, delta=None, borderType=None)
參數(shù):
ddepth:圖像深度。ddepth=-1表示目標(biāo)圖像與原始圖像使用相同的圖像深度
示例:
import cv2
import numpy
img = cv2.imread("image/1.jpg")
# 1.定義一個(gè)卷積核
kernel = numpy.float32([[1, 1, 0], [1, 0, -1], [0, -1, -1]])
# 2.卷積操作
dst = cv2.filter2D(img, -1, kernel)
cv2.imshow("iamge", img)
cv2.imshow("dst", dst)
cv2.waitKey(0)
cv2.destroyAllWindows()
結(jié)果如下:

三、平滑操作(低通濾波)
函數(shù):
2.平滑操作(低通濾波)
1)均值濾波:blur(src, ksize)
2)中值濾波:medianBlur(src, ksize),ksize為大于1的奇數(shù)
中值濾波一般用于處理椒鹽噪聲。
3)高斯濾波:GaussianBlur(src, ksize, sigmaX, dst=None, sigmaY=None, borderType=None)
ksize為奇數(shù),
sigmaX是高斯函數(shù)在x軸方向上的標(biāo)準(zhǔn)差。
sigmaY是高斯函數(shù)在y軸方向上的標(biāo)準(zhǔn)差。若不指定sigmaY,則sigmaY=sigmaX。
4)雙邊濾波:bilateralFilter(src, d, sigmaColor, sigmaSpace, dst=None, borderType=None)
d是每個(gè)像素的領(lǐng)域直徑,
sigmaColor:在顏色空間中的過濾sigma。
sigmaSpace:在坐標(biāo)系空間中的過濾sigma。
sigma為無窮大時(shí),效果等價(jià)于高斯模糊。sigma為0時(shí),與原圖一樣。
高斯濾波和雙邊濾波的區(qū)別:
1)高斯核只考慮了空間分布,沒有考慮到像素值的差異,會(huì)將圖像的邊緣模糊掉。
2)雙邊濾波是基于高斯濾波提出的,結(jié)合了圖像的空間鄰近度和像素值相似度的一種折衷處理,具有保邊特性。
示例:
import cv2
img1 = cv2.imread("image/5.jpg")
img2 = cv2.imread("image/25.jpg")
# 1.均值濾波: blur(src, ksize, dst=None, anchor=None, borderType=None)
mean = cv2.blur(img1, ksize=(5, 5))
# 2.中值濾波: medianBlur(src, ksize, dst=None) ksize為大于1的奇數(shù)
median = cv2.medianBlur(img1, ksize=7)
# 3.高斯濾波: GaussianBlur(src, ksize, sigmaX, dst=None, sigmaY=None, borderType=None)
# ksize為奇數(shù)
# sigmaX是高斯函數(shù)在x軸方向上的標(biāo)準(zhǔn)差。若不指定sigmaY,則sigmaY=sigmaX。
gaussian = cv2.GaussianBlur(img2, ksize=(7, 7), sigmaX=6, sigmaY=6)
# 4.雙邊濾波: bilateralFilter(src, d, sigmaColor, sigmaSpace, dst=None, borderType=None)
# d是每個(gè)像素的領(lǐng)域直徑
# sigmaColor:在顏色空間中的過濾sigma。sigmaSpace:在坐標(biāo)系空間中的過濾sigma。
# sigma為無窮大時(shí),效果等價(jià)于高斯模糊。sigma為0時(shí),與原圖一樣。
bilateral = cv2.bilateralFilter(img2, 9, 75, 75)
# bilateral = cv2.bilateralFilter(img2, 9, 0, 0)
cv2.imshow("img1", img1)
cv2.imshow("mean", mean)
cv2.imshow("median", median)
cv2.imshow("img2", img2)
cv2.imshow("gaussian", gaussian)
cv2.imshow("bilateral", bilateral)
cv2.waitKey(0)
cv2.destroyWindow()
結(jié)果如下:


四、銳化操作(高通濾波)
示例:
import cv2
import numpy
src = cv2.imread("image/1.jpg")
# 1.自定義銳化核
kernel = numpy.float32([[0, -1, 0], [-1, 5, -1], [0, -1, 0]])
dst1 = cv2.filter2D(src, -1, kernel)
# 2.USM銳化(UnsharpMask)
gaussian = cv2.GaussianBlur(src, (5, 5), 6)
dst2 = cv2.addWeighted(src, 2, gaussian, -1, 0)
cv2.imshow("src", src)
cv2.imshow("dst1", dst1)
cv2.imshow("dst2", dst2)
cv2.waitKey(0)
cv2.destroyWindow()
結(jié)果如下:

五、梯度操作(高通濾波)
梯度算子有 Sobel、Scharr 和 Laplacian算子。
Sobel 和 Scharr 其實(shí)就是求一階或二階導(dǎo)數(shù)。Scharr 是對(duì) Sobel(使用小的卷積核求解求解梯度角度時(shí))的優(yōu)化。而Laplacian 是求二階導(dǎo)數(shù)。
Sobel 算子是高斯平滑與微分操作的結(jié)合體,所以它的抗噪聲能力很好。
Scharr 濾波器是對(duì)Sobel濾波器的改進(jìn)版本。




函數(shù):
4.梯度操作(高通濾波)
1)Sobel算子
Sobel(src, ddepth, dx, dy, dst=None, ksize=None, scale=None, delta=None, borderType=None)
dx和dy表示的是求導(dǎo)的階數(shù),0表示這個(gè)方向上沒有求導(dǎo),一般為0、1、2。
2)Scharr算子
Scharr(src, ddepth, dx, dy, dst=None, scale=None, delta=None, borderType=None)
dx和dy表示的是求導(dǎo)的階數(shù),0表示這個(gè)方向上沒有求導(dǎo),一般為0、1、2。
3)Laplacian算子
Laplacian(src, ddepth, dst=None, ksize=None, scale=None, delta=None, borderType=None)
示例:
import cv2
import matplotlib.pyplot as plt
gray = cv2.imread("image/2.jpg", cv2.IMREAD_GRAYSCALE)
# 1.Sobel算子: dx和dy表示的是求導(dǎo)的階數(shù),0表示這個(gè)方向上沒有求導(dǎo),一般為0、1、2。
sobel_x = cv2.Sobel(gray, -1, dx=1, dy=0) # x軸方向上的一階導(dǎo)數(shù)
sobel_y = cv2.Sobel(gray, -1, dx=0, dy=1) # y軸方向上的一階導(dǎo)數(shù)
sobel_x_abs = cv2.convertScaleAbs(sobel_x)
sobel_y_abs = cv2.convertScaleAbs(sobel_y)
sobel = cv2.addWeighted(sobel_x, 0.5, sobel_y, 0.5, 0) # 近似有|G|=|Gx|+|Gy|
# 2.Scharr算子: dx和dy表示的是求導(dǎo)的階數(shù),0表示這個(gè)方向上沒有求導(dǎo),一般為0、1、2。
scharr_x = cv2.Scharr(gray, -1, dx=1, dy=0) # x軸方向上的一階導(dǎo)數(shù)
scharr_y = cv2.Scharr(gray, -1, dx=0, dy=1) # y軸方向上的一階導(dǎo)數(shù)
scharr_x_abs = cv2.convertScaleAbs(scharr_x)
scharr_y_abs = cv2.convertScaleAbs(scharr_y)
scharr = cv2.addWeighted(scharr_x_abs, 0.5, scharr_y_abs, 0.5, 0) # 近似有|G|=|Gx|+|Gy|
# 近似有|G|=|Gx|+|Gy|
# 3.Laplacian算子
laplacian = cv2.Laplacian(gray, -1)
# 結(jié)合matplotlib顯示多張圖片
titles = ['Original Gray', 'Sobel x', 'Sobel y', 'Sobel', 'Scharr x', 'Scharr y', 'Scharr', 'Laplacian']
images = [gray, sobel_x, sobel_y, sobel, scharr_x, scharr_y, scharr, laplacian]
for i in range(8):
plt.subplot(2, 4, i + 1)
plt.imshow(images[i], cmap="gray")
plt.title(titles[i])
plt.xticks([]), plt.yticks([])
plt.show()
結(jié)果如下:
