1. 程式人生 > >引導濾波原理及C++程式碼實現

引導濾波原理及C++程式碼實現

前置內容

在學習引導濾波,最好對高斯濾波和雙邊濾波有過理解,對於高斯濾波: W i j = 1 K

i e x p ( x
j
x i 2
σ
2
) W_{ij} = \frac{1}{K_i}exp(-\frac{|x_j-x_i|^2}{\sigma^2}) ,其中 W W 是權重, i i j j 是畫素的索引, K K 是歸一化的常量。公式可以看出,權重只和畫素之間的空間距離有關係存在關係,濾波效果和影象內容無關。所以為了增加對不同的影象有不同的濾波效果,引入了雙邊濾波,雙邊濾波的形式為: W i , j = 1 K i e x p ( x j x i 2 σ s 2 ) e x p ( I j I i 2 σ r 2 ) W_{i,j}=\frac{1}{K_i}exp(-\frac{|x_j-x_i|^2}{\sigma_s^2})exp(-\frac{|I_j-I_i|^2}{\sigma_r^2}) ,其中 I I 是畫素的強度值,所以雙邊濾波在強度差距大的地方(邊緣),權重會減小,濾波效應會減少。也就是說,雙邊濾波在畫素強度變化不大的區域,有類似於高斯濾波的效果,而在影象邊緣等畫素強度梯度較大的地方可以保持梯度。

引導濾波

這個方法是何凱明提出的,在引導濾波中,首先利用了局部線性模型。這個模型認為某函式上一點與其近鄰部分的點成線性關係,一個複雜的函式就可以用很多區域性的線性函式來表示,當需要求該函式上某一點的值時,只需要計算所有包含該點的線性函式的值並取平均值即可。這種模型,在表示非解析函式上,非常有用。同理,我們可以認為影象是一個二維函式,並且假設該函式的輸出與輸入在一個二維視窗內滿足線性關係,如下: q i = a k I i + b k , i w k q_i=a_kI_i+b_k, \forall i \in w_k 其中,q是輸出畫素的值,I是輸入影象的值,i和k是畫素索引,a和b是當視窗中心位於k時該線性函式的係數。其實,輸入影象不一定是待濾波的影象本身,也可以是其他影象即引導影象,這也是為何稱為引導濾波的原因。對上式兩邊取梯度,可以得到 q = a I \partial q = a \partial I 即當輸入影象I有梯度時,輸出q也有類似的梯度,現在可以解釋為什麼引導濾波有邊緣保持特性了。下一步是求出線性函式的係數,也就是線性迴歸,即希望擬合函式的輸出值與真實值p之間的差距最小,也就是讓下式最小 E ( a k , b k ) = i w k ( ( a k I i + b k p i ) 2 + ε a k 2 ) E(a_k, b_k)=\sum_{i\in w_k}{((a_kI_i + b_k - p_i)^2 + \varepsilon a_k^2)} ,這裡p只能是待濾波影象,並不像I那樣可以是其他影象。同時,a之前的係數用於防止求得的a過大,也是調節濾波器濾波效果的重要引數(相當於L2正則化的權重懲罰)。接下來利用最小二乘法的原理令 E a k = 0 \frac{\partial E}{\partial a_k}=0 E b k = 0 \frac{\partial E}{b_k}=0 得到2個二元一次方程,聯立求解得到 a k = 1 w i w k I i p i u k p ˉ k σ k 2 + ε a_k = \frac{\frac{1}{w}\sum_{i\in w_k}I_ip_i-u_k\bar p_k}{\sigma_k^2+\varepsilon} b k = p ˉ k a k u k b_k=\bar p_k - a_ku_k ,其中 u k u_k 是I在視窗 w k w_k 的平均值, σ k 2 \sigma_k^2 是I在視窗 w k w_k 的方差, w |w| 是視窗 w k w_k