圖像去霧(二)Retinex圖像增強算法

前一段時間研究了一下圖像增強算法,發現Retinex理論在彩色圖像增強、圖像去霧、彩色圖像恢復方面擁有很好的效果,下面介紹一下我對該算法的理解。

Retinex理論

    Retinex理論始於Land和McCann於20世紀60年代作出的一系列貢獻,其基本思想是人感知到某點的顏色和亮度並不僅僅取決於該點進入人眼的絕對光線,還和其周圍的顏色和亮度有關。Retinex這個詞是由視網膜(Retina)和大腦皮層(Cortex)兩個詞組合構成的.Land之所以設計這個詞,是爲了表明他不清楚視覺系統的特性究竟取決於此兩個生理結構中的哪一個,抑或是與兩者都有關係。

     Land的Retinex模型是建立在以下的基礎之上的:

     一、真實世界是無顏色的,我們所感知的顏色是光與物質的相互作用的結果。我們見到的水是無色的,但是水膜—肥皂膜卻是顯現五彩繽紛,那是薄膜表面光干涉的結果;

     二、每一顏色區域由給定波長的紅、綠、藍三原色構成的;

     三、三原色決定了每個單位區域的顏色。Retinex 理論的基本內容是物體的顏色是由物體對長波(紅)、中波(綠)和短波(藍)光線的反射能力決定的,而不是由反射光強度的絕對值決定的;物體的色彩不受光照非均性的影響,具有一致性,即Retinex理論是以色感一致性(顏色恆常性)爲基礎的。如下圖所示,觀察者所看到的物體的圖像S是由物體表面對入射光L反射得到的,反射率R由物體本身決定,不受入射光L變化。

                                                          

Retinex理論的基本假設是原始圖像S是光照圖像L和反射率圖像R的乘積,即可表示爲下式的形式:

                                                                

基於Retinex的圖像增強的目的就是從原始圖像S中估計出光照L,從而分解出R,消除光照不均的影響,以改善圖像的視覺效果,正如人類視覺系統那樣。在處理中,通常將圖像轉至對數域,即

                                                                

從而將乘積關係轉換爲和的關係:

                                                                     

Retinex方法的核心就是估測照度L,從圖像S中估測L分量,並去除L分量,得到原始反射分量R,即:

                                                                          

函數 f(x) 實現對照度L的估計(可以去這麼理解,實際很多都是直接估計r分量)。

Retinex理論的理解

如果大家看論文,那麼在接下去的篇幅當中,肯定會介紹兩個經典的Retinex算法:基於路徑的Retinex以及基於中心/環繞Retinex。在介紹兩個經典的Retinex算法之前,我先來講一點個人的理解,以便第一次接觸該理論的朋友能夠更快速地理解。當然,如果我的理解有問題,也請大家幫忙指出。

Retinex理論就我理解,與降噪類似,該理論的關鍵就是合理地假設了圖像的構成。如果將觀察者看到的圖像看成是一幅帶有乘性噪聲的圖像,那麼入射光的分量就是一種乘性的,相對均勻,且變換緩慢的噪聲。Retinex算法所做的就是合理地估計圖像中各個位置的噪聲,併除去它。

在極端情況下,我們大可以認爲整幅圖像中的分量都是均勻的,那麼最簡單的估計照度L的方式就是在將圖像變換到對數域後對整幅圖像求均值。因此,我設計了以下算法來驗證自己的猜想,流程如下:

(1) 將圖像變換到對數域

                                                                               

(2) 歸一化去除加性分量

                                                                             

(3) 對步驟3得到的結果求指數,反變換到實數域

                                                                           

這裏爲了簡化描述,省略了對圖像本身格式的變換,算法用Matlab實現:

% ImOriginal:原始圖像
% type:'add'表示分量是加性的,如霧天圖像;'mult'表示分量是乘性的,如對照度的估計
[m,n,z] = size(ImOriginal);
ImOut = uint8(zeros(m,n,z));
for i = 1:z
    if strcmp(type,'add')
        ImChannel = double(ImOriginal(:,:,i))+eps;
    elseif strcmp(type,'mult')
        ImChannel = log(double(ImOriginal(:,:,i))+eps);
    else
        error('type must be ''add'' or ''mult''');
    end
    ImOut(:,:,i) = EnhanceOneChannel(ImChannel);
end
ImOut = max(min(ImOut,255), 0);
end

function ImOut = EnhanceOneChannel(ImChannel)
% 計算計算單個通道的反射分量
% 1.對全圖進行照射分量估計
% 2.減去照射分量
% 3.灰度拉伸
ImChannel = ImChannel./max(ImChannel(:));
ImRetinex = round(exp(ImChannel.*5.54));
ImOut = uint8(ImRetinex);
end

                                                               

                                                                               測試原圖

                                                               

                                                                          經典Retinex算法結果

                                                               

                                                                           上述方法結果

從對比中可以看到,對於去除照度,還原圖像本身來講,效果還可以,並且不會在邊緣位置產生光暈現象。缺點就是在去除照度分量L過程中,保留的反射分量R我在上述算法中使用歸一化後直接進行反變換。這一步的作用可以近似看成去除一個均勻的直流分量,即均勻的照度分量。由於操作都是全局的,這裏默認假設了所有位置的照射分量都是相同的,因此在灰度拉伸的時候沒有照顧到局部的特性,圖像整體亮度偏暗。當然,全局的照度估計對於圖像的增強肯定有相當的侷限性,其增強效果在色彩的還原和亮度處理等方面還是有一定缺陷的。

個人認爲,Retinex算法的關鍵還是正確的分析了噪聲的性質。相信很多人都看到利用基於Retinex的圖像水下增強、基於Retinex的圖像去霧等等,我也好奇,那就試試吧。大霧圖片嘛誰沒有,前一陣子大霧天,沒事拍了幾張照片,終於用上了,請看對比圖:

                                                             

                                                                                 有霧原圖

                                                             

                                                                        經典Retinex去霧效果

                                                              

                                                                         上述方法去霧效果

還是老規矩,這時候對比試驗還是最能說明效果的,爲此選了一幅干擾很大的圖像。基本上各位要是顯示器比較差一點,從原圖當中是很難看出大霧後面的東西。從去霧效果來看,上述方法的效果並不比經典算法要差,至少在去霧的效果上,本實驗結果從主觀上給人的感覺還是不錯的。

在上述案例中,最重要的就是正確分析有霧圖像的結構,與Retinex理論一開始的核心思想有區別的是,在針對這種加性的干擾時,經典的Retinex算法在處理過程中,其實僅僅是利用其估計加性的干擾分量;當然,拋開Retinex理論對照度、反射率對最終圖像形成的核心思想(如圖1),後續最重要的就是對這個加性的干擾的估計了。

對於有霧的圖像,我們大可以看作透過一塊磨砂玻璃去看一幅清晰的圖像,這樣大家就能很好理解爲什麼認爲在這個案例中,將霧的干擾認爲是一個加性的了。諸如後面兩個經典的算法,所有的這類算法歸根結底就是更好地利用原圖像中的像素點去估計原始照度。從上面例程上可以看出,使用一個全局估計對局部的增強是比較差的,如果存在照度不均勻(霧的濃度不均勻),或者背景顏色亮度很高等情況時,處理結果會趨向惡劣,效果比較差。

當然,經典也不是完美,從圖中可以看到,經典的算法容易出現光暈效果(藍色書本文字周圍一圈白色)。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章