圖像噪聲
由于圖像采集、處理等過程都存在一定的誤差而存在響應的噪聲。其中苍狰,噪聲包括高斯噪聲、均勻分布噪聲呐伞、脈沖噪聲(椒鹽噪聲)等
高斯噪聲(Gaussian noise)
由于高斯噪聲在空間和頻域中數學上的易處理性,這種噪聲(也稱為正態(tài)噪聲)模型經常被用于實踐中慎式。高斯隨機變量z的Probability Density Function(PDF)由下式給出:
其中z表示灰度值伶氢,μ表示z的平均值或期望值,σ表示z的標準差瘪吏。標準差的平方σ2稱為z的方差癣防。高斯函數的曲線如圖所示。
當z服從上式的高斯分布時候掌眠,其值有70%落在[(μ-σ),(μ+σ)]內蕾盯,有95%落在[(μ-2σ),( μ+2σ)]范圍內。
均勻分布噪聲 (Uniform noise)
均勻噪聲分布的概率密度:
概率密度函數的期望值和方差可由下式給出:
脈沖噪聲(椒鹽噪聲)
(雙極)脈沖噪聲的PDF:
如果b>a级遭,灰度值b在圖像中將顯示為一個亮點,a的值將顯示為一個暗點渺尘。若Pa或Pb為零挫鸽,則脈沖噪聲稱為單極脈沖。如果Pa和Pb均不可能為零鸥跟,尤其是它們近似相等時丢郊,脈沖噪聲值將類似于隨機分布在圖像上的胡椒和鹽粉微粒。由于這個原因锌雀,雙極脈沖噪聲也稱為椒鹽噪聲蚂夕。同時,它們有時也稱為散粒和尖峰噪聲腋逆。
噪聲脈沖可以是正的,也可以是負的侈贷。在一幅圖像中惩歉,脈沖噪聲總是數字化為最小值或最大值(純黑或純白)等脂。負脈沖以一個黑點(胡椒點)出現在圖像中。由于相同的原因撑蚌,正脈沖以白點(鹽點)出現在圖像中上遥。
圖像平滑(圖像模糊)
在已知噪聲模型的基礎上,對噪聲的空間域濾波争涌。
主要包括:均值濾波器粉楚、中值濾波器、高斯模糊亮垫、雙邊濾波器模软。
均值濾波器(Mean Filters)
采用均值濾波模板對圖像噪聲進行濾除。令 表示中心在(x, y)點饮潦,尺寸為m×n 的矩形子圖像窗口的坐標組燃异。
均值濾波器
由一個歸一化卷積框完成的。它只是用卷積框覆蓋區(qū)域所有像素的平均值來代替中心元素继蜡』乩可以使用函數 cv2.blur() 和 cv2.boxFilter() 來完這個任務。
注意:如果你不想使用歸一化卷積框稀并,你應該使用 cv2.boxFilter()仅颇,這時要傳入參數 normalize=False。
cv2.blur(src, dst, ksize, anchor, borderType)
參數意義如下:
- src:輸入圖像
- dst:輸出圖像
- ksize:卷積核的大小
- anchor:默認值 (-1,-1) 碘举,表示核中心
- borderType:邊界類型灵莲,參見圖像擴邊
例子
def img_show(name,img):
"""matplotlib圖像顯示函數
name:字符串,圖像標題
img:numpy.ndarray殴俱,圖像
"""
if len(img.shape) == 3:
img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
plt.imshow(img,'gray')
#plt.xticks([])
#plt.yticks([])
plt.xlabel(name,fontproperties='FangSong',fontsize=12)
if __name__=="__main__":
img1 = cv2.imread("Fig0333(a)(test_pattern_blurring_orig).tif")
img2 = cv2.blur(img1,(5,5))
plt.figure(figsize=(10,8),dpi=80)
plt.subplot(121)
img_show('原圖',img1)
plt.subplot(122)
img_show('均值濾波',img2)
高斯模糊(Gaussian Blur)
由于Gaussian函數有著一些良好的特性政冻,對二維連續(xù)Gaussian分布經采樣、量化线欲,并使模板歸一化明场,便可得到二維Gaussian濾波模板。
是高斯分布的標準差李丰,又稱濾波器的尺度苦锨,決定了高斯濾波器作用鄰域的空間范圍。隨著逐漸遠離濾波中心趴泌,G(x,y)權值逐漸減小到零舟舒,這表明離濾波器中心較近的像素比遠處的像素更重要。因此嗜憔,高斯低通濾波器是一種加權均值濾波器秃励。
把卷積核換成高斯核(簡單來說,方框不變吉捶,將原來每個方框的值是相等的夺鲜,現在里面的值是符合高斯分布的皆尔,方框中心的值最大,其余方框根據距離中心元素的距離遞減币励,構成一個高斯小山包慷蠕。原來的求平均數現在變成求加權平均數,全就是方框里的值)食呻。實現的函數是 cv2.GaussianBlur()流炕。我們需要指定高斯核的寬和高(必須是奇數)。以及高斯函數沿 X仅胞,Y 方向的標準差每辟。如果我們只指定了 X 方向的的標準差,Y 方向也會取相同值饼问。如果兩個標準差都是 0影兽,那么函數會根據核函數的大小自己計算。高斯濾波可以有效的從圖像中去除高斯噪音莱革。如果你愿意的話峻堰,你也可以使用函數 cv2.getGaussianKernel() 自己構建一個高斯核。
如果要使用高斯模糊的話盅视,上邊的代碼應該寫成:
GaussianBlur(src, ksize, sigmaX, sigmaY, borderType)
#0是指根據窗口大芯杳(5,5)來計算高斯函數標準差
blur = cv2.GaussianBlur(img,(5,5),0)
參數意義如下:
- src:輸入圖像
- ksize:卷積核的大小
- sigmaX:在X方向高斯分布的標準差(二維高斯核函數可以拆分成水平方向和豎直方向的一維高斯核函數)
- sigmaY:在Y方向高斯分布的標準差(如果只會設置sigmaX,默認sigmaY=sigmaX)
- borderType:邊界類型
例子:對椒鹽噪聲的圖像進行高斯模糊
def img_show(name,img):
"""matplotlib圖像顯示函數
name:字符串闹击,圖像標題
img:numpy.ndarray镶蹋,圖像
"""
if len(img.shape) == 3:
img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
plt.imshow(img,'gray')
#plt.xticks([])
#plt.yticks([])
plt.xlabel(name,fontproperties='FangSong',fontsize=12)
if __name__=="__main__":
img1 = cv2.imread("Fig0335(a)(ckt_board_saltpep_prob_pt05).tif")
# img2 = cv2.blur(img1,(5,5))
img2 = cv2.GaussianBlur(img1,(7,7),0)
img3 = cv2.GaussianBlur(img1,(7,7),5)
img4 = cv2.GaussianBlur(img1,(7,7),10)
plt.figure(figsize=(10,8),dpi=80)
plt.subplot(221)
img_show('原圖',img1)
plt.subplot(222)
img_show('高斯模糊($\sigma$=0)',img2)
plt.subplot(223)
img_show('高斯模糊($\sigma$=5)',img3)
plt.subplot(224)
img_show('高斯模糊($\sigma$=10)',img4)
中值濾波器(Median filter)
中值濾波可去掉椒鹽噪聲,平滑效果優(yōu)于均值濾波赏半,在抑制隨機噪聲的同時能保持圖像邊緣少受模糊贺归。
這個濾波器經常用來去除椒鹽噪聲。前面的濾波器都是用計算得到的一個新值來取代中心像素的值断箫,而中值濾波是用中心像素周圍(也可以使他本身)的值來取代它拂酣。它能有效的去除噪聲。卷積核的大小也應該是一個奇數仲义。
median = cv2.medianBlur(src,dst,ksize)
參數意義如下:
- src:輸入圖像
- dst:輸出圖像
- ksize:卷積核的大小
例子
def img_show(name,img):
"""matplotlib圖像顯示函數
name:字符串婶熬,圖像標題
img:numpy.ndarray,圖像
"""
if len(img.shape) == 3:
img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
plt.imshow(img,'gray')
#plt.xticks([])
#plt.yticks([])
plt.xlabel(name,fontproperties='FangSong',fontsize=12)
if __name__=="__main__":
img1 = cv2.imread("Fig0335(a)(ckt_board_saltpep_prob_pt05).tif")
img2 = cv2.medianBlur(img1,5)
plt.figure(figsize=(10,8),dpi=80)
plt.subplot(121)
img_show('原圖',img1)
plt.subplot(122)
img_show('中值濾波',img2)
雙邊濾波(bilateral Filter)
函數 cv2.bilateralFilter() 能在保持邊界清晰的情況下有效的去除噪音埃撵。但是這種操作與其他濾波器相比會比較慢赵颅。我們已經知道高斯濾波器是求中心點鄰近區(qū)域像素的高斯加權平均值。這種高斯濾波器只考慮像素之間的空
間關系暂刘,而不會考慮像素值之間的關系(像素的相似度)饺谬。所以這種方法不會考慮一個像素是否位于邊界。因此邊界也會別模糊掉鸳惯,而這正不是我們想要商蕴。雙邊濾波在同時使用空間高斯權重和灰度值相似性高斯權重叠萍≈シⅲ空間高斯函
數確保只有鄰近區(qū)域的像素對中心點有影響绪商,灰度值相似性高斯函數確保只有與中心像素灰度值相近的才會被用來做模糊運算。所以這種方法會確保邊界不會被模糊掉辅鲸,因為邊界處的灰度值變化比較大格郁。
雙邊濾波是一種非線性的濾波方法,是結合圖像的空間鄰近度和像素值相似度的一種折中處理独悴,同時考慮空域信息和灰度相似性例书,優(yōu)點是可以做邊緣保存。在邊緣附近刻炒,離得較遠的像素不會對邊緣上的像素值影響太多决采,這樣就保證了邊緣附近像素值的保存。但是由于保存了過多的高頻信息坟奥,對于彩色圖像里的高頻噪聲树瞭,雙邊濾波器不能很好地濾掉,只能對低頻噪聲很好地濾波爱谁。
cv2.bilaralFilter(src,dst,d,sigmaColor,sigmaSpace,borderType=BORDER_DEFAULT)
#9 鄰域直徑晒喷,兩個75分別是空間高斯函數標準差,灰度值相似性高斯函數標準差
blur = cv2.bilateralFilter(img,9,75,75)
參數意義如下:
- src:輸入圖像
- dst:輸出圖像
- d:表示在過濾過程中每個像素鄰域的直徑访敌。如果這個值被設為非正數凉敲,那么opencv會從第五個參數sigmaSpace來計算出她。
- sigmaColor:顏色空間濾波器的sigma值寺旺,這個參數的值越大爷抓,就表明該像素領域內有越寬廣的顏色會被混到一起
- sigmaSpace:坐標空間濾波器的sigma值,坐標空間的標注方差阻塑。它的數值越大蓝撇,意味著越遠的像素會相互影響,從而使更大的區(qū)域中足夠相似的顏色獲取相同的顏色叮姑,當d>0時唉地,d指定了尺寸,此參數沒什么用传透,否則耘沼,d正比于這個參數值。
- borderType:用于推斷圖像外部像素的某種邊界模式朱盐。
例子
def img_show(name,img):
"""matplotlib圖像顯示函數
name:字符串群嗤,圖像標題
img:numpy.ndarray,圖像
"""
if len(img.shape) == 3:
img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
plt.imshow(img,'gray')
#plt.xticks([])
#plt.yticks([])
plt.xlabel(name,fontproperties='FangSong',fontsize=12)
if __name__=="__main__":
img1 = cv2.imread("gooey.jpg")
img2 = cv2.bilateralFilter(img1,9,75,75)
plt.figure(figsize=(10,8),dpi=80)
plt.subplot(121)
img_show('原圖',img1)
plt.subplot(122)
img_show('雙邊濾波',img2)
參考文獻:《數字圖像處理》《OpenCV-Python 中文教程》