? ? ? ? 無論是平均平滑還是高斯平滑,在處理圖像噪聲時(shí),都或多或少會(huì)對圖片產(chǎn)生一定的模糊,損失部分信息。較為理想的情況,是可以選擇性地進(jìn)行濾波,只在噪聲區(qū)域進(jìn)行平滑,而在無噪聲區(qū)域不進(jìn)行平滑,將模糊的影響降到最低,這就是自適應(yīng)性濾波的思想。通常噪聲的存在,可能會(huì)使得附近鄰域內(nèi),極值的上下差距較大,或者是方差較大,我們可以設(shè)置一定的閾值來判斷該點(diǎn)是否需要進(jìn)行平滑。不過這個(gè)不是該章節(jié)的內(nèi)容,這一章是要學(xué)習(xí)中值濾波,中值濾波本質(zhì)上是一個(gè) 統(tǒng)計(jì)排序?yàn)V波器 ,是以該點(diǎn)為中心的的鄰域內(nèi)的所有像素的統(tǒng)計(jì)排序中值作為該點(diǎn)的響應(yīng);而平滑就是加權(quán)平均數(shù)作為響應(yīng),概念上有一定差別。
? ? ? ?不同的濾波器在處理不同類型的噪聲是效果不同,對于線性平滑濾波,在處理像素鄰域內(nèi)的噪聲點(diǎn)時(shí),噪聲或多或少都會(huì)影響該點(diǎn)的像素值計(jì)算(以高斯平滑為例,距離近則影響大,距離遠(yuǎn)則影響小,與距離的平方呈反比);但是中值濾波通常可以將噪聲點(diǎn)直接忽略掉。同時(shí),中值濾波在降噪的同時(shí)引起的模糊效應(yīng)較低。中值濾波的一種典型應(yīng)用,就是用來消除椒鹽(salt & pepper)噪聲。于是我們先編寫一個(gè)函數(shù)來為我們的灰度圖像添加椒鹽噪聲。
from PIL import Image
import numpy as np
def AddNoise(src, dst, probility = 0.05, method = "salt_pepper"):
imarray = np.array(Image.open(src))
height, width = imarray.shape
for i in range(height):
for j in range(width):
if np.random.random(1) < probility:
if np.random.random(1) < 0.5:
imarray[i, j] = 0
else:
imarray[i, j] = 255
new_im = Image.fromarray(imarray)
new_im.save(dst)
gray_girl = "C:/Users/60214/Desktop/python_work/DigitalExecution/gray_girl.jpg"
tar = "C:/Users/60214/Desktop/python_work/DigitalExecution/gray_girl_saltpepper.jpg"
AddNoise(gray_girl, tar)
? ? ? ?處理之后的圖像如下,這就是椒鹽噪聲。
? ? ? ? ?使用平均模板處理之后的圖像如下,圖片變模糊的同時(shí)并沒有消除椒鹽噪聲。雖然沒有擺圖,但是如果使用高斯平滑,也是同樣的效果,椒鹽噪聲的影響依舊存在。
? ? ? ? ? 使用一個(gè)3x3尺寸的中值濾波來處理含有突發(fā)性的椒鹽噪聲的代碼如下。其中我們選擇的填充方式是無填充,也就是對圖像邊緣,上下左右處忽略掉不進(jìn)行濾波,只對可以容納下一個(gè)濾波模板的區(qū)域?yàn)V波。這樣子的做法好處是代碼編寫起來比較簡單,而一般情況下圖像邊緣出的信息不是那么重要所以這樣子做的風(fēng)險(xiǎn)比較小。另外,執(zhí)行尋找中值的用numpy自帶的median方法,我們也可以自己寫一個(gè)排序算法來執(zhí)行。
from PIL import Image
import numpy as np
def MedianFilter(src, dst, k = 3, padding = None):
imarray = np.array(Image.open(src))
height, width = imarray.shape
if not padding:
edge = int((k-1)/2)
if height - 1 - edge <= edge or width - 1 - edge <= edge:
print("The parameter k is to large.")
return None
new_arr = np.zeros((height, width), dtype = "uint8")
for i in range(height):
for j in range(width):
if i <= edge - 1 or i >= height - 1 - edge or j <= edge - 1 or j >= height - edge - 1:
new_arr[i, j] = imarray[i, j]
else:
new_arr[i, j] = np.median(imarray[i - edge:i + edge + 1, j - edge:j + edge + 1])
new_im = Image.fromarray(new_arr)
new_im.save(dst)
src = "C:/Users/60214/Desktop/python_work/DigitalExecution/gray_girl_saltpepper.jpg"
dst = "C:/Users/60214/Desktop/python_work/DigitalExecution/aaa.jpg"
MedianFilter(src, dst)
?? ? ? 代碼運(yùn)行的結(jié)果是得到一張?zhí)幚砗蟮膱D像,如上圖所示。可以看到確實(shí)把絕大部分的椒鹽點(diǎn)都去除了,除了在邊緣上一個(gè)像素寬度的區(qū)域有一些零星的點(diǎn)。但是,跟其他平滑的結(jié)果類似的,中值濾波也使得圖像的清晰度有所下降。這是因?yàn)樵谔幚硪恍┻吘壍臅r(shí)候也采用了中值濾波,導(dǎo)致了清晰度的下降。所以如果要解決這個(gè)問題,可以在對像素點(diǎn)賦予鄰域的中位數(shù)之前添加一個(gè)判斷條件。因?yàn)槲覀冎溃肼暎际菙?shù)值與附近的區(qū)域相差很大,接近0或者是255,也就是很大可能是附近鄰域內(nèi)的極值。所以我們的判斷條件就是,該像素是否是濾波窗口覆蓋下鄰域的極大值或極小值,如果是就進(jìn)行中值濾波;如果不是就不予處理。修改后的新的代碼為
from PIL import Image
import numpy as np
def BetterMedianFilter(src, dst, k = 3, padding = None):
imarray = np.array(Image.open(src))
height, width = imarray.shape
if not padding:
edge = int((k-1)/2)
if height - 1 - edge <= edge or width - 1 - edge <= edge:
print("The parameter k is to large.")
return None
new_arr = np.zeros((height, width), dtype = "uint8")
for i in range(height):
for j in range(width):
if i <= edge - 1 or i >= height - 1 - edge or j <= edge - 1 or j >= height - edge - 1:
new_arr[i, j] = imarray[i, j]
else:
#nm:neighbour matrix
nm = imarray[i - edge:i + edge + 1, j - edge:j + edge + 1]
max = np.max(nm)
min = np.min(nm)
if imarray[i, j] == max or imarray[i, j] == min:
new_arr[i, j] = np.median(nm)
else:
new_arr[i, j] = imarray[i, j]
new_im = Image.fromarray(new_arr)
new_im.save(dst)
src = "C:/Users/60214/Desktop/python_work/DigitalExecution/gray_girl_saltpepper.jpg"
dst = "C:/Users/60214/Desktop/python_work/DigitalExecution/aaaa.jpg"
MedianFilter(src, dst)
? ? ? ?下圖是k=3是的改進(jìn)后的中值濾波策略的結(jié)果,可以看到圖像的清晰度得到了較大的保留,噪聲的數(shù)量就相對也殘留的比較多。從中可以看到,二者之間有此消彼長的關(guān)系。至于為什么還有這么多的椒鹽噪聲,原因是因?yàn)槲覀兲砑釉肼暤拇a中設(shè)置的概率太高了,導(dǎo)致圖像中的椒鹽噪聲數(shù)量非常多,在小區(qū)域內(nèi)有可能有許多的噪聲點(diǎn),導(dǎo)致算法所尋找到的中值仍然是噪聲的數(shù)值范圍。這種情況下擴(kuò)大濾波模板的大小并不會(huì)有多大的改變。此時(shí)可以將已經(jīng)執(zhí)行過一次中值濾波的結(jié)果圖像再執(zhí)行一次中值濾波,效果就會(huì)更好一些。
執(zhí)行了一次改良過的中值濾波的結(jié)果
執(zhí)行了兩次改良過的中值濾波的結(jié)果
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061
微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元

