過濾是信號和圖像處理中基本的任務。其目的是根據應用環境的不同,選擇性的提取圖像中某些認為是重要的信息。過濾可以移除圖像中的噪音、提取感興趣的可視特征、允許圖像重采樣等等。頻域分析將圖像分成從低頻到高頻的不同部分。低頻對應圖像強度變化小的區域,而高頻是圖像強度變化非常大的區域。在頻率分析領域的框架中,濾波器是一個用來增強圖像中某個波段或頻率並阻塞(或降低)其他頻率波段的操作。低通濾波器是消除圖像中高頻部分,但保留低頻部分。高通濾波器消除低頻部分。參考博客:https://blog.csdn.net/sunny2038/article/details/9155893
個人認為模糊操作就是過濾掉圖像中的一些特殊噪音。
具體模糊和濾波的關系如下圖:參考知乎大神:https://www.zhihu.com/question/54918332/answer/142137732

一、均值模糊、中值模糊、用戶自定義模糊
代碼如下:
#均值模糊、中值模糊、自定義模糊 模糊是卷積的一種表象 import cv2 as cv import numpy as np def blur_demo(image): #均值模糊 去隨機噪聲有很好的去燥效果 dst = cv.blur(image, (1, 15)) #(1, 15)是垂直方向模糊,(15, 1)還水平方向模糊 cv.namedWindow('blur_demo', cv.WINDOW_NORMAL) cv.imshow("blur_demo", dst) def median_blur_demo(image): # 中值模糊 對椒鹽噪聲有很好的去燥效果 dst = cv.medianBlur(image, 5) cv.namedWindow('median_blur_demo', cv.WINDOW_NORMAL) cv.imshow("median_blur_demo", dst) def custom_blur_demo(image): # 用戶自定義模糊 kernel = np.ones([5, 5], np.float32)/25 #除以25是防止數值溢出 dst = cv.filter2D(image, -1, kernel) cv.namedWindow('custom_blur_demo', cv.WINDOW_NORMAL) cv.imshow("custom_blur_demo", dst) src = cv.imread('E:\imageload\lenanoise.jpg') cv.namedWindow('input_image', cv.WINDOW_NORMAL) cv.imshow('input_image', src) blur_demo(src) median_blur_demo(src) custom_blur_demo(src) cv.waitKey(0) cv.destroyAllWindows()
運行結果:

注意:
1.均值濾波是典型的線性濾波算法,它是指在圖像上對目標像素給一個模板,該模板包括了其周圍的臨近像素(以目標像素為中心的周圍8個像素,構成一個濾波模板,即去掉目標像素本身),再用模板中的全體像素的平均值來代替原來像素值。
低通濾波(均值模糊)函數原型:blur(src, ksize[, dst[, anchor[, borderType]]]) -> dst
src參數表示待處理的輸入圖像。
ksize參數表示模糊內核大小。比如(1,15)表示生成的模糊內核是一個1*15的矩陣。
dst參數表示輸出與src相同大小和類型的圖像。
anchor參數、borderType參數可忽略
2.中值濾波法是一種非線性平滑技術,它將每一像素點的灰度值設置為該點某鄰域窗口內的所有像素點灰度值的中值。具體原理參見博客:https://blog.csdn.net/weixin_37720172/article/details/72627543
中值濾波(中值模糊)函數原型:medianBlur(src, ksize[, dst]) -> dst
src參數表示待處理的輸入圖像。
ksize參數表示濾波窗口尺寸,必須是奇數並且大於1。比如這里是5,中值濾波器就會使用5×5的范圍來計算,即對像素的中心值及其5×5鄰域組成了一個數值集,對其進行處理計算,當前像素被其中值替換掉。
dst參數表示輸出與src相同大小和類型的圖像。
3.用戶自定義模糊
所用函數:filter2D()
函數原型: filter2D(src, ddepth, kernel[, dst[, anchor[, delta[, borderType]]]]) -> dst
src參數表示待處理的輸入圖像。
ddepth參數表示目標圖像深度,輸入值為-1時,目標圖像和原圖像深度保持一致
kernel: 卷積核(或者是相關核),一個單通道浮點型矩陣。修改kernel矩陣即可實現不同的模糊
二、高斯模糊
代碼如下:
#高斯模糊 輪廓還在,保留圖像的主要特征 高斯模糊比均值模糊去噪效果好 import cv2 as cv import numpy as np def clamp(pv): if pv > 255: return 255 if pv < 0: return 0 else: return pv def gaussian_noise(image): #加高斯噪聲 h, w, c = image.shape for row in range(h): for col in range(w): s = np.random.normal(0, 20, 3) b = image[row, col, 0] #blue g = image[row, col, 1] #green r = image[row, col, 2] #red image[row, col, 0] = clamp(b + s[0]) image[row, col, 1] = clamp(g + s[1]) image[row, col, 2] = clamp(r + s[2]) cv.namedWindow("noise image", cv.WINDOW_NORMAL) cv.imshow("noise image", image) dst = cv.GaussianBlur(image, (15, 15), 0) # 高斯模糊 cv.namedWindow("Gaussian", cv.WINDOW_NORMAL) cv.imshow("Gaussian", dst) src = cv.imread('E:\imageload\lena.jpg') cv.namedWindow("input_image", cv.WINDOW_NORMAL) cv.imshow('input_image', src) gaussian_noise(src) dst = cv.GaussianBlur(src, (15,15), 0) #高斯模糊 cv.namedWindow("Gaussian Blur", cv.WINDOW_NORMAL) cv.imshow("Gaussian Blur", dst) cv.waitKey(0) cv.destroyAllWindows()
運行結果:

注意:
1.高斯模糊實質上就是一種均值模糊,只是高斯模糊是按照加權平均的,距離越近的點權重越大,距離越遠的點權重越小。通俗的講,高斯濾波就是對整幅圖像進行加權平均的過程,每一個像素點的值,都由其本身和鄰域內的其他像素值經過加權平均后得到。
2.高斯分布的一維和二維原理如下:

補:高斯分布的標准差σ。標准差代表着數據的離散程度,如果σ較小,那么生成的模板的中心系數較大,而周圍的系數較小,這樣對圖像的平滑效果就不是很明顯;反之,σ較大,則生成的模板的各個系數相差就不是很大,比較類似均值模板,對圖像的平滑效果比較明顯。高斯模糊具體原理見博文:https://blog.csdn.net/u012992171/article/details/51023768
3.高斯模糊GaussianBlur函數原型:GaussianBlur(src, ksize, sigmaX[, dst[, sigmaY[, borderType]]]) -> dst
src參數表示待處理的輸入圖像。
ksize參數表示高斯濾波器模板大小。 ksize.width和ksize.height可以不同,但它們都必須是正數和奇數。或者,它們可以是零,即(0, 0),然后從σ計算出來。
sigmaX參數表示 X方向上的高斯內核標准差。
sigmaY參數表示 Y方向上的高斯內核標准差。 如果sigmaY為零,則設置為等於sigmaX,如果兩個sigma均為零,則分別從ksize.width和ksize.height計算得到。
補:若ksize不為(0, 0),則按照ksize計算,后面的sigmaX沒有意義。若ksize為(0, 0),則根據后面的sigmaX計算ksize
4.numpy包里的random模塊用於生成隨機數,random模塊里的normal函數表示的是生成高斯隨機數。
normal函數默認原型:normal(loc=0.0, scale=1.0, size=None)。
loc參數表示高斯分布的中心點。
scale參數表示高斯分布的標准差σ。
size參數表示產生隨機數的個數。size取值可以為(m,n,k),表示繪制m*n*k個樣本。
三、邊緣保留濾波EPF
進行邊緣保留濾波通常用到兩個方法:高斯雙邊濾波和均值遷移濾波。
代碼如下:
#邊緣保留濾波(EPF) 高斯雙邊、均值遷移 import cv2 as cv import numpy as np def bi_demo(image): #雙邊濾波 dst = cv.bilateralFilter(image, 0, 100, 15) cv.namedWindow("bi_demo", cv.WINDOW_NORMAL) cv.imshow("bi_demo", dst) def shift_demo(image): #均值遷移 dst = cv.pyrMeanShiftFiltering(image, 10, 50) cv.namedWindow("shift_demo", cv.WINDOW_NORMAL) cv.imshow("shift_demo", dst) src = cv.imread('E:/imageload/example.png') cv.namedWindow('input_image', cv.WINDOW_NORMAL) cv.imshow('input_image', src) bi_demo(src) shift_demo(src) cv.waitKey(0) cv.destroyAllWindows()
運行結果:

注意:
1.雙邊濾波(Bilateral filter)是一種非線性的濾波方法,是結合圖像的空間鄰近度和像素值相似度的一種折中處理,同時考慮空域信息和灰度相似性,達到保邊去噪的目的。雙邊濾波器顧名思義比高斯濾波多了一個高斯方差sigma-d,它是基於空間分布的高斯濾波函數,所以在邊緣附近,離的較遠的像素不會太多影響到邊緣上的像素值,這樣就保證了邊緣附近像素值的保存。但是由於保存了過多的高頻信息,對於彩色圖像里的高頻噪聲,雙邊濾波器不能夠干凈的濾掉,只能夠對於低頻信息進行較好的濾波
2.雙邊濾波函數原型:bilateralFilter(src, d, sigmaColor, sigmaSpace[, dst[, borderType]]) -> dst
src參數表示待處理的輸入圖像。
d參數表示在過濾期間使用的每個像素鄰域的直徑。如果輸入d非0,則sigmaSpace由d計算得出,如果sigmaColor沒輸入,則sigmaColor由sigmaSpace計算得出。
sigmaColor參數表示色彩空間的標准方差,一般盡可能大。較大的參數值意味着像素鄰域內較遠的顏色會混合在一起,從而產生更大面積的半相等顏色。
sigmaSpace參數表示坐標空間的標准方差(像素單位),一般盡可能小。參數值越大意味着只要它們的顏色足夠接近,越遠的像素都會相互影響。當d > 0時,它指定鄰域大小而不考慮sigmaSpace。 否則,d與sigmaSpace成正比。
雙邊濾波原理:
https://blog.csdn.net/edogawachia/article/details/78837988,https://blog.csdn.net/MoFMan/article/details/77482794 ,https://www.cnblogs.com/qiqibaby/p/5296681.html 反正我是沒怎么看懂o(╥﹏╥)o
3.均值漂移pyrMeanShiftFiltering函數原型:pyrMeanShiftFiltering(src, sp, sr[, dst[, maxLevel[, termcrit]]]) -> dst
src參數表示輸入圖像,8位,三通道圖像。
sp參數表示漂移物理空間半徑大小。
sr參數表示漂移色彩空間半徑大小。
dst參數表示和源圖象相同大小、相同格式的輸出圖象。
maxLevel參數表示金字塔的最大層數。
termcrit參數表示漂移迭代終止條件。
均值漂移原理:
https://blog.csdn.net/dcrmg/article/details/52705087
