使用工具:Python3.5
使用庫:cv2
1.2D卷積
同一維信號一樣,可以對2D圖像實施低通濾波(LPF)和高通濾波(HPF)。LPF用于去除噪音,模糊圖像,HPF用于找到圖像的邊緣。
OpenCV提供的函數cv.filter2D()可以對一幅圖像進行卷積操作。練習一幅圖像使用平均濾波器。舉例下面是一個5X5的平均濾波器核:

操作如下,將核放在圖像的一個像素A上,求與核對應的圖像上25(5x5)個像素的和,再取平均數,用這個平均數代替像素A的值。重復以上操作直到將圖像的每一個像素值都更新一遍。
~~~
import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('1024.jpg')
kernel = np.ones((5,5),np.float32)/25
#cv.Filter2D(src, dst, kernel, anchor=(-1, -1))
#ddepth –desired depth of the destination image;
#if it is negative, it will be the same as src.depth();
#the following combinations of src.depth() and ddepth are supported:
#src.depth() = CV_8U, ddepth = -1/CV_16S/CV_32F/CV_64F
#src.depth() = CV_16U/CV_16S, ddepth = -1/CV_32F/CV_64F
#src.depth() = CV_32F, ddepth = -1/CV_32F/CV_64F
#src.depth() = CV_64F, ddepth = -1/CV_64F
#when ddepth=-1, the output image will have the same depth as the source.
dst = cv2.filter2D(img,-1,kernel)
plt.subplot(121),plt.imshow(img),plt.title('original')
plt.xticks([]),plt.yticks([])
plt.subplot(122),plt.imshow(dst),plt.title('averaging')
plt.xticks([]),plt.yticks([])
plt.show()
~~~
2.平均
這是由一個歸一化卷積框完成的,他只是用卷積框覆蓋區域所有像素的平均值來代替中心元素。可以使用cv2.blur()和cv2.boxFilter()來實現, 我們需要設定卷積框的寬和高。同樣是一個矩陣。
~~~
import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('1024.jpg')
blur = cv2.blur(img,(5,5))
while(1):
cv2.imshow('image',img)
cv2.imshow('blur',blur)
k=cv2.waitKey(1)
if k == ord('q'):#按q鍵退出
break
cv2.destroyAllWindows()
~~~
原文使用plt來顯示,但是結果有出入,這里改為cv2.imshow,會更明顯。

下面是plt顯示結果

3.高斯模糊
現在把卷積核換成高斯核,簡單的說方框不變,將原來每個方框的值是相等的,現在里面的值是符合高斯分布的,方框中心的值最大,其余方框根據距離中心元素的距離遞減,構成一個高斯小山包,原來的求平均數變成求加權平均數,權就是方框里的值。實現的函數是cv2.GaussianBlur()。需要指定高斯核的寬和高(必須是奇數),以及高斯函數沿X,Y方向的標準差。如果我們只指定了X方向的標準差,Y方向也會取相同值,如果兩個標準差都是0.那么函數會根據核函數的大小自己計算,高斯濾波可以有效的從圖像中去除高斯噪音。
也可以使用cv2.getGaussianKernel()自己構建一個高斯核。
如果要使用高斯模糊的話,上邊的代碼應改成:
~~~
# 0是指根據窗口大小(5,5)來計算高斯函數標準差
blur = cv2.GaussianBlur(img,(5,5),0)
~~~
4.中值模糊
就是用與卷積框對應像素的中值來替代中心像素的值,這個濾波器經常用來去除椒鹽噪聲。前面的濾波器都是用計算得到的一個新值來取代中心像素的值,而中值濾波是用中心像素周圍或者本身的值來取代他,他能有效去除噪聲。卷積核的大小也應該是一個奇數。
需要給原始圖像加上50%的噪聲,然后用中值模糊。
~~~
median = cv2.medianBlur(img,5)
~~~
5.雙邊濾波
函數cv2.bilateralFilter()能在保持邊界清晰的情況下有效的去除噪音,但比較慢。這種高斯濾波器只考慮像素之間的空間關系,而不會考慮像素值之間的關系(像素的相似度),所以這種方法不會考慮一個像素是否位于邊界,因此邊界也會被模糊掉。
雙邊濾波在同時使用空間高斯權重和灰度值相似性高斯權重。空間高斯函數確保只有鄰近區的像素對中心點有影響,灰度值相似性高斯函數確保只有與中心像素灰度值相近的才會被用來做模糊運算。所以能保證邊界不會被模糊,因此邊界處的灰度值變化比較大。
~~~
#cv2.bilateralFilter(src, d, sigmaColor, sigmaSpace)
#d – Diameter of each pixel neighborhood that is used during filtering. # If it is non-positive, it is computed from sigmaSpace
# 9 鄰域直徑,兩個 75 分別是空間高斯函數標準差,灰度值相似性高斯函數標準差
blur = cv2.bilateralFilter(img,9,75,75)
~~~