同態濾波及影象去陰影
影象照度不均勻,或者有陰影怎麼進行二值化?相信長期做機器視覺的朋友都遇到過,下面分享我個人的一些經驗,如果有更好的方法請不吝指出,共同進步。
1、影象亮度不均勻分析
一般情況下,影象f(x,y)是由光源產生的照度場i(x,y)和目標的反射係數場r(x,y)共同作用產生的,且前者可以表達成後二者的乘積,即:
f(x,y) = i(x,y) r(x,y)
r(x,y)反映的是目標表面顏色和紋理等特徵,是我們最需要的資訊。i(x,y)反映的是光源相對於目標的方位及強度分佈。在機器視覺專案中,光源的佈置及本身特性會造成對目標的照射不均勻。
2、同態濾波及去陰影
如果對f(x,y)做對數變換,可以將照度場i(x,y)與反射係數場r(x,y)分離開來,即
ln f(x,y) = ln i(x,y) + ln r(x,y)
再做傅立葉變換即
F{ln f(x,y)} = F{ln i(x,y)} + F{ln r(x,y)}
或者寫為
G(u,v) = I(u,v) + R(u,v)
其中,G(u,v)、I(u,v)和R(u,v)分別是ln f(x,y)、ln i(x,y)和ln r(x,y)的傅立葉變換。
如果通過一個傳遞函式H(u,v)對G(u,v)進行處理,即
S(u,v) = H(u,v) G(u,v) = H(u,v)I(u,v) + H(u,v)R(u,v)
前面講到,r(x,y)反映的是目標表面顏色和紋理等特徵,可以看成是影象的高頻成分,i(x,y)反映的是光源相對於目標的方位和強度分佈,一般變化緩慢,可以看做影象的低頻成分。如果H(u,v)選擇合適的高通濾波器,由上面公式可以看出目標特徵可以得到保持,而低頻的照度不均會得到抑制。
對S(u,v)進行傅立葉反變換之後再做指數運算,即可得到原影象的同態濾波結果。
另外,在頻域裡對G(u,v)乘以H(u,v)等效於在空域裡對ln f(x,y)以H(u,v)的傅立葉反變換為卷積核做卷積。下面的Matlab示例我們就採用這種方法。
3、Matlab示例
如下圖所示,左邊為原圖,右邊為同態濾波後的結果,可以看出影象整體上亮度變得均勻了。但是影象高頻部分也受到了一定的影響,這可以通過構造更合適的高通濾波器進行改善。clear; close all; %載入原始影象 img = imread('graph.bmp'); figure, imshow(img); title('初始影象'); %構造高通濾波器 filter1 = fspecial('gaussian', [7 7], 0.6); filter2 = fspecial('gaussian', [7 7], 1.2); high_pass = filter1 - filter2; %利用對數變換將入射光和反射光部分分開 log_img = log(1.0 + double(img)); %將高斯高通濾波器與對數轉換後的影象卷積 high_log_part = imfilter(log_img, high_pass, 'symmetric', 'conv'); %顯示卷積後的影象 figure, imshow(high_log_part); %冪變換回來 high_part = exp(high_log_part) - 1.0; minv = min(min(high_part)); maxv = max(max(high_part)); %顯示結果影象 resultImg = (high_part - minv) / (maxv - minv); figure, imshow(resultImg); title('同態濾波結果'); imwrite(resultImg, 'homoResult.bmp');
4、結語
同態濾波是改善影象照度不均的一種方法,以便於後續二值化等操作。但是對於照度不均勻或陰影影象還有另外一些自適應二值化的方法,我會在以後文章中跟大家分享。