本文分享自華為云社區(qū)《[Python從零到壹] 五十六.圖像增強(qiáng)及運(yùn)算篇之圖像平滑(中值濾波、雙邊濾波)》,作者: eastmount 。
一.中值濾波原文詳情:https://bbs.huaweicloud.com/blogs/386509?utm_source=juejin&utm_medium=bbs-ex&utm_campaign=other&utm_content=content
前面講述的都是線性平滑濾波,它們的中間像素值都是由鄰域像素值線性加權(quán)得到的,接下來將講解一種非線性平滑濾波——中值濾波。中值濾波通過計(jì)算每一個(gè)像素點(diǎn)某鄰域范圍內(nèi)所有像素點(diǎn)灰度值的中值,來替換該像素點(diǎn)的灰度值,從而讓周圍的像素值更接近真實(shí)情況,消除孤立的噪聲。
中值濾波對脈沖噪聲有良好的濾除作用,特別是在濾除噪聲的同時(shí),能夠保護(hù)圖像的邊緣和細(xì)節(jié),使之不被模糊處理,這些優(yōu)良特性是線性濾波方法所不具有的,從而使其常常被應(yīng)用于消除圖像中的椒鹽噪聲[1-2]。
中值濾波算法的計(jì)算過程如圖1所示。選擇含有五個(gè)點(diǎn)的窗口,依次掃描該窗口中的像素,每個(gè)像素點(diǎn)所對應(yīng)的灰度值按照升序或降序排列,然后獲取最中間的值來替換該點(diǎn)的灰度值。
上圖展示的是矩形窗口,常用的窗口還包括正方形、十字形、環(huán)形和圓形等,不同形狀的窗口會(huì)帶來不同的過濾效果,其中正方形和圓形窗口適合于外輪廓邊緣較長的圖像,十字形窗口適合于帶尖角形狀的圖像。
OpenCV將中值濾波封裝在medianBlur()函數(shù)中,其函數(shù)原型如下所示:
– src表示待處理的輸入圖像
– dst表示輸出圖像,其大小和類型與輸入圖像相同
– ksize表示內(nèi)核大小,其值必須是大于1的奇數(shù),如3、5、7等
下面是調(diào)用medianBlur()函數(shù)實(shí)現(xiàn)中值濾波的代碼。
# -*- coding: utf-8 -*-# By:Eastmountimport cv2 import numpy as np import matplotlib.pyplot as plt#讀取圖片img = cv2.imread('lena-zs.png')source = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)#中值濾波result = cv2.medianBlur(source, 3)#用來正常顯示中文標(biāo)簽plt.rcParams['font.sans-serif']=['SimHei']#顯示圖形titles = ['原始圖像', '中值濾波']images = [source, result]for i in range(2): plt.subplot(1,2,i+1), plt.imshow(images[i], 'gray') plt.title(titles[i]) plt.xticks([]),plt.yticks([])plt.show()
其運(yùn)行結(jié)果如圖2所示,它有效地過濾掉了“l(fā)ena”圖中的噪聲,并且很好地保護(hù)了圖像的邊緣信息,使之不被模糊處理。
二.雙邊濾波雙邊濾波(Bilateral filter)是由Tomasi和Manduchi在1998年發(fā)明的一種各向異性濾波,它一種非線性的圖像平滑方法,結(jié)合了圖像的空間鄰近度和像素值相似度(即空間域和值域)的一種折中處理,從而達(dá)到保邊去噪的目的。雙邊濾波的優(yōu)勢是能夠做到邊緣的保護(hù),其他的均值濾波、方框?yàn)V波和高斯濾波在去除噪聲的同時(shí),都會(huì)有較明顯的邊緣模糊,對于圖像高頻細(xì)節(jié)的保護(hù)效果并不好[3]。
雙邊濾波比高斯濾波多了一個(gè)高斯方差sigma-d,它是基于空間分布的高斯濾波函數(shù)。所以在圖像邊緣附近,離的較遠(yuǎn)的像素點(diǎn)不會(huì)過于影響到圖像邊緣上的像素點(diǎn),從而保證了圖像邊緣附近的像素值得以保存。但是雙邊濾波也存在一定的缺陷,由于它保存了過多的高頻信息,雙邊濾波不能有效地過濾掉彩色圖像中的高頻噪聲,只能夠?qū)Φ皖l信息進(jìn)行較好地去噪[4]。
在雙邊濾波器中,輸出的像素值依賴于鄰域像素值的加權(quán)值組合,對輸入圖像進(jìn)行局部加權(quán)平均得到輸出圖像 的像素值,其公式如下所示:
式中表示中心點(diǎn)(x,y)的(2N+1)×(2N+1)的領(lǐng)域像素,值依賴于領(lǐng)域像素值的加權(quán)平均。權(quán)重系數(shù)取決于空間域核(domain)和值域核(range)的乘積。空間域核的定義如公式(2)所示。
值域核的定義如公式(3)所示。
兩者相乘之后,就會(huì)產(chǎn)生依賴于數(shù)據(jù)的雙邊濾波權(quán)重函數(shù),如下所示:
從式子(4)可以看出,雙邊濾波器的加權(quán)系數(shù)是空間鄰近度因子和像素亮度相似因子的非線性組合。前者隨著像素點(diǎn)與中心點(diǎn)之間歐幾里德距離的增加而減小,后者隨著像素亮度之差的增大而減小[5-6]。
在圖像變化平緩的區(qū)域,鄰域內(nèi)亮度值相差不大,雙邊濾波器轉(zhuǎn)化為高斯低通濾波器;在圖像變化劇烈的區(qū)域,鄰域內(nèi)像素亮度值相差較大,濾波器利用邊緣點(diǎn)附近亮度值相近的像素點(diǎn)的亮度平均值替代原亮度值。因此,雙邊濾波器既平滑了圖像,又保持了圖像邊緣,其原理圖如圖3所示。
OpenCV將中值濾波封裝在bilateralFilter()函數(shù)中,其函數(shù)原型如下所示:
– src表示待處理的輸入圖像
– dst表示輸出圖像,其大小和類型與輸入圖像相同
– d表示在過濾期間使用的每個(gè)像素鄰域的直徑。如果這個(gè)值我們設(shè)其為非正數(shù),則它會(huì)由sigmaSpace計(jì)算得出
– sigmaColor表示顏色空間的標(biāo)準(zhǔn)方差。該值越大,表明像素鄰域內(nèi)較遠(yuǎn)的顏色會(huì)混合在一起,從而產(chǎn)生更大面積的半相等顏色區(qū)域
– sigmaSpace表示坐標(biāo)空間的標(biāo)準(zhǔn)方差。該值越大,表明像素的顏色足夠接近,從而使得越遠(yuǎn)的像素會(huì)相互影響,更大的區(qū)域中相似的顏色獲取相同的顏色,當(dāng)d>0,d指定了鄰域大小且與sigmaSpace無關(guān)。否則,d正比于sigmaSpace
– borderType表示邊框模式,用于推斷圖像外部像素的某種邊界模式,默認(rèn)值為BORDER_DEFAULT,可省略
下面是調(diào)用bilateralFilter()函數(shù)實(shí)現(xiàn)雙邊濾波的代碼,其中d為15,sigmaColor設(shè)置為150,sigmaSpace設(shè)置為150。
# -*- coding: utf-8 -*-# By:Eastmountimport cv2 import numpy as np import matplotlib.pyplot as plt #讀取圖片img = cv2.imread('lena-zs.png')source = cv2.cvtColor(img,cv2.COLOR_BGR2RGB) #雙邊濾波result = cv2.bilateralFilter(source, 15, 150, 150)#用來正常顯示中文標(biāo)簽plt.rcParams['font.sans-serif']=['SimHei']#顯示圖形titles = ['原始圖像', '雙邊濾波'] images = [source, result]for i in range(2): plt.subplot(1,2,i+1), plt.imshow(images[i], 'gray') plt.title(titles[i]) plt.xticks([]),plt.yticks([])plt.show()
其運(yùn)行結(jié)果如圖4所示:
三.總結(jié)本文主要講解了常用于消除噪聲的圖像平滑方法,常見方法包括三種線性濾波(均值濾波、方框?yàn)V波、高斯濾波)和兩種非線性濾波(中值濾波、雙邊濾波)。這篇文章介紹了中值濾波和雙邊濾波,通過原理和代碼進(jìn)行對比,分別講述了各種濾波方法的優(yōu)缺點(diǎn),有效地消除了圖像的噪聲,并保留圖像的邊緣輪廓。
參考文獻(xiàn):
關(guān)注#華為云開發(fā)者聯(lián)盟#,第一時(shí)間了解華為云新鮮技術(shù)~