数字图像学笔记——8. 几种常见的空间滤波器(均值滤波器、中值滤波器)
在上一章里,簡要的介紹了空間濾波器,在這一章節中將實現幾種常見的空間濾波器函數。
文章目錄
- 什么是濾波
- 空間濾波(Spatial Filtering)
- 均值濾波器(Mean Filter)
- 中值濾波器(Median Filter)
什么是濾波
濾波的概念主要出自信號學領域,指的是過濾我們不感興趣的信號頻段。最早使用濾波技術的,應該最早出自無線電領域,通過可調電容來完成濾波。大家比較熟悉的一種物理濾波應用,就是收音機了,學習數字圖像領域的朋友倒是不太需要了解電容對于信號的濾波作用,所以這里也不必過多的展開。
空間濾波(Spatial Filtering)
雖然都是濾波,但是在圖像領域有兩類比較重要的濾波技術,一種是空間濾波,另一種是頻域濾波。而對于視頻圖像分析,則有另外一類被稱為時域濾波的技術。不過數字圖像處理主要介紹到空間和頻率。
在之前的章節里,我已經簡單的介紹了一些圖像增強技術,你可以簡單的理解為對輸入的像素IiI_iIi?,套用某個公式或者算法fsf_sfs?,然后得到一個輸出IoI_oIo?的過程,寫作一個公式的話,就表示為:
Io=Ii?fsI_o = I_i \bigodot f_sIo?=Ii??fs?
對像素點的逐點計算,與矩陣概念上的 哈達瑪積(hadamard product) 很相似。只不過與Hadamard product不一樣的地方在于,空間濾波函數通常不是一次性的把全部像素點放入到 fsf_sfs? 里進行處理,而是每次取出一小塊,再逐次地拿到 fsf_sfs? 處理函數里進行計算。
我在 Wikipedia 上看到一張有意思的動圖,它是一個均值濾波函數,左邊是原始數據,中間是濾波核,右邊則是處理后的結果,它很好的解釋了什么是空間濾波,以及空間濾波函數的計算過程。
你或許已經注意到在這里定義了一個核函數,也就是中間 3×33 \times 33×3 的部分,它包含9個值,每個值都是1/9。在原圖像進行處理的時候,我們讓這個被定義的核函數,依次平滑地掃過每一個點,然后從紅框所包含的像素里,分別讀取9個像素值,然后和我們定義的核函數相乘,再把每一個結果相加起來,寫做數學公式,簡單一點,就成了:
P1?K1+P2?K2+P3?K3+?+P9?K9=Pij?P_1 \cdot K_1 + P_2 \cdot K_2 + P_3 \cdot K_3 + \cdots + P_9 \cdot K_9 = P_{ij}^{*}P1??K1?+P2??K2?+P3??K3?+?+P9??K9?=Pij??
這里的K,表示的是每個原始像素對新像素值的貢獻值,或者稱為權重,而P則是9個不同的像素點的值。
簡化一下這個表達過程,于是再次推導出我們的一個通用計算公式:Io=Ii?fsI_o = I_i \bigodot f_sIo?=Ii??fs?
而為了表示紅框逐像素點處理的過程,在很多教材上你會看到它的這樣一個表示方式:
Io=∑∑Ii,j?fsI_o = \sum \sum I_{i,j} \bigodot f_sIo?=∑∑Ii,j??fs?
它的核心思想就是,想要得到某種效果的輸出矩陣(圖像),它是由原始圖像,與某種操作共同組合而成,而且這個操作必然需要逐點(逐快)掃描,這個過程有點像你拿放大鏡觀察物體的過程,而負責處理這個最終像素生成的過程就是所謂的空間濾波器了。
這里的 fsf_sfs? 即空間濾波器的核函數,它可以是某個數學函數,也可以是我們自己用代碼實現的具備某種特殊處理方法,比如對于數值大于15的輸入一律輸出為0。看到這里,你是不是躍躍欲試,想自己開發一種特別的數據處理方法?
盡管不排除可以自己設計某種特殊濾波器的天才,不過通常情況下,我們普通人都會用數學家、或者信號學家發明的一系列工具,用于圖像細節增強、降噪,或者提取特征,除了有時會覺得這樣做調參很麻煩,但是終歸利大于弊。
均值濾波器(Mean Filter)
均值濾波器,其核函數經常寫成如下的解析式:
K=1Kw×Kh∑f(x,y)?W(x,y)K = \frac{1}{K_w \times K_h} \sum f(x, y) \cdot W(x, y) K=Kw?×Kh?1?∑f(x,y)?W(x,y)
這里的KwK_wKw? 和 KhK_hKh? 表示的是核函數的長和寬,后面表示待處理的部分各像素的貢獻權重,并求和。它的實現代碼可以簡單的寫成如下形式
def mean_kernel(image):mean = 9width, height = image.shapebackup = np.zeros(image.shape, np.uint8)for i in range(1, width - 1):for j in range(1, height - 1):px000 = int(image[i - 1][j - 1])px001 = int(image[i][j - 1])px002 = int(image[i + 1][j - 1])px010 = int(image[i - 1][j])px011 = int(image[i][j])px012 = int(image[i + 1][j])px100 = int(image[i - 1][j + 1])px101 = int(image[i][j + 1])px102 = int(image[i + 1][j + 1])sigma = px000 + px001 + px002 +\px010 + px011 + px012 +\px100 + px101 + px102backup[i][j] = round(sigma / mean)return backup輸出的圖像效果如下:
仔細觀察妹子身上衣服的紋樣,可以發現模糊了很多;把核函數的平均尺寸如果設置為5x5甚至更大,那么平滑效果(模糊效果)也就越明顯了。例如使用5x5的平均核,得到的效果就是這樣的了。
需要注意一點的是,從像素讀取中讀取的數據類型為byte,長度為8,直接讓像素跟像素加和,很容易出現 Bit-flip 的現象,導致計算結果失敗,所以安全的方法是讀取數據后做一道數值格式轉換。
中值濾波器(Median Filter)
與均值濾波器相似,只不過在賦值環節,有所不同。它要求
首先 將讀取的像素值按照大小進行排序
然后 選取排序后中間的數值,或者中間數值的平均
這是一種常用的,用于處理類似椒鹽噪音那樣,孤點信號的特殊方法。舉例來說,對于3×33 \times 33×3 濾波核來說,假如讀取了一組信號,它是
對數據進行排列后為
[0,2,3,3,4,6,10,15,97][0, 2, 3, 3, 4, 6,10,15, 97][0,2,3,3,4,6,10,15,97]
那么處理后,中間97的值就應該表示為4
其代碼實現為:
那么,我們生成一副帶椒鹽噪音的照片后,再用這個濾波函數處理一下,看看效果如何
當然,仔細觀察還原后的圖像,任然會發現一些細節出現了模糊,其實這里,選擇合適的kernel size就顯得非常關鍵,我用的是5x5,如果用3x3會好一點,不過這也要看圖像包含的噪音情況是不是很嚴重就是了。
總結
以上是生活随笔為你收集整理的数字图像学笔记——8. 几种常见的空间滤波器(均值滤波器、中值滤波器)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Matlab中函数imnoise使用浅谈
- 下一篇: c语言常用例子,C语言经典例子100个