相關隨筆可見:帶色彩恢復的多尺度視網膜增強算法(MSRCR)的原理、實現及應用。
從歷史的順序上講,本篇應該放在MSRCR之前的,只是由於現在大多論文都是描述的MSRCR,因此我也是先學習MSRCR的。
今天,無意中找尋一些Retinex資料,搜索到一篇文章《Retinex in matlab》,原以為是MSRCR之類的matlab實現,結果仔細一看,和MSRCR算法的描述完全不同。於是找了一些資料,對Retinex的歷史有了進一步了解,以下復制一些論文中的文檔以供說明:
******************************************************************************************************************************************************************************
文章地址:http://www.doc88.com/p-993974139685.html
近年來,在現代生理學和心理學的啟發下,美國物理學家Land等人設計出了Retinex(視網膜皮層)模型,並在符合人眼的顏色恆常性理論前提下,提出了基於Retinex的圖像增強算法。這種算法建立的基礎是假設人眼感知目標的亮度和顏色由環境光照和目標表面的反射光照決定,保持目標的顏色恆常性主要就是估計環境光照,並去除環境光照的影像。這樣就得到了准確的目標顏色和亮度信息。由於Retinex算法具有高動態范圍壓縮、高色彩保真度和良好的局部細節增強等特點,引起了大量的國外學者的興趣。為准確估計亮度分量,選取計算路徑常見有一維和二維的區別。早期,Land提出選取隨機路徑,並對路徑所經過的像素進行累加計算亮度,這種方法的缺陷在於當前像素點的亮度和隨機路徑上的像素亮度有關和其領域周圍的像素亮度幾乎無關,使得增強后的圖像出現亮度不連續的現象。隨后出現了兩種迭代分段線性路徑,即McCann99 Retinex 和Frankle-McCann Retinex,相比隨機路徑的Retinex而言,他們的增強效果較好。然而,他們的共同缺陷在於計算復雜度比較高,且迭代次數的選擇對增強效果的影響至關重要。2004年,Ciurea和Funt發表了自動選擇迭代次數的論文后,這一難題才得以解決。 Land分析了一維路徑選擇的缺陷,提出了二維路徑的選擇方式,即中心/環繞Retinex算法。這種方式下,當前像素點周圍領域內像素亮度值作為計算依據,且Jobson等人嚴謹的證明了高斯卷積函數滿足中心/環繞函數要求...........................................(以下就是SSR\MSR\MSRCR...等等)。
******************************************************************************************************************************************************************************
由以上描述可見,Frankle-McCann Retinex采用了一維路徑尋找方式估計亮度,而MSRCR是二維的,后者則更為復雜。
關於FMR算法的原理呢,我一下子也講不清,這里稍微對算法的一些過程進行簡單的介紹吧。
首先,算法的輸入需要是[0,1]范圍的浮點數,並且是按對數分布的,這個通常需要將[0,255]按對數方式量化到[0,1]范圍內。
然后按照下圖所示的路徑對每個點的數據進行相比、想乘、復位和平均操作。

這個我實在是說不清楚了,給幾個鏈接大家自己看看吧:
基於心理物理學評價和偏愛映射的高動態范圍圖像的色調映射算子的設計
最后把處理的數據從對數域轉換到[0,255]范圍內(這里需要使用exp函數哦)。
我們還是把時間放在算法效果的簡要分析上。

一般情況下,可以認為FMR算法只有迭代次數一個參數。由上圖可見,迭代次數越小,圖像的對比度越小,連讀越亮,動態壓縮范圍越小。迭代次數越大,圖像的對比度越強烈。從直方圖上看,迭代次數小時,直方圖會聚集在一起,隨着迭代次數等增加,直方圖逐漸分布到全部動態范圍內。 當迭代次數特別大時,圖像會和原始圖像很接近。
我們在貼一些該算法處理的結果。



原圖 迭代兩次 迭代10次
可見,對一些偏暗的圖像的增強效果還是很明顯。
經過測試證明,這個算法對於我們在正常光照下拍攝的照片的處理有意想不到的效果,可以產生類似HDR的效果,貼出如下:


原圖 處理后
另外,該算法對偏色圖像也有一定的糾偏能力,比如下圖。


原圖 處理后
貼出一段比較粗糙的實現該函數的matlab代碼:
function Test() clear all rgb=imread('c:\222.jpg');%需要處理的圖片 m=size(rgb,1); n=size(rgb,2); rr=zeros(m,n); gg=zeros(m,n); bb=zeros(m,n); for i=1:m for j=1:n rr(i,j)=logm(double(rgb(i,j,1))+eps); gg(i,j)=logm(double(rgb(i,j,2))+eps); bb(i,j)=logm(double(rgb(i,j,3))+eps); end end rr=rr/max(max(rr(:))); gg=gg/max(max(gg(:))); bb=bb/max(max(bb(:))); rrr= retinex_frankle_mccann(rr, 4); ggg= retinex_frankle_mccann(gg, 4); bbb= retinex_frankle_mccann(bb, 4); for i=1:m for j=1:n rrr(i,j)=round(exp(rrr(i,j)*5.54)); ggg(i,j)=round(exp(ggg(i,j)*5.54)); bbb(i,j)=round(exp(bbb(i,j)*5.54)); end end rgb=cat(3,uint8(rrr),uint8(ggg),uint8(bbb)); rgb=max(min(rgb,255),0); imshow(rgb); end function [ Retinex ] = retinex_frankle_mccann( L, nIterations ) global RR IP OP NP Maximum RR = L; Maximum = max(L(:)); % maximum color value in the image [nrows, ncols] = size(L); shift = 2^(fix(log2(min(nrows, ncols)))-1); % initial shift OP = Maximum*ones(nrows, ncols); % initialize Old Product while (abs(shift) >= 1) for i = 1:nIterations CompareWith(0, shift); % horizontal step CompareWith(shift, 0); % vertical step end shift = -shift/2; % update the shift end Retinex = NP; end function CompareWith(s_row, s_col) global RR IP OP NP Maximum IP = OP; if (s_row + s_col > 0) IP((s_row+1):end, (s_col+1):end) = OP(1:(end-s_row), 1:(end-s_col)) + ... RR((s_row+1):end, (s_col+1):end) - RR(1:(end-s_row), 1:(end-s_col)); else IP(1:(end+s_row), 1:(end+s_col)) = OP((1-s_row):end, (1-s_col):end) + ... RR(1:(end+s_row),1:(end+s_col)) - RR((1-s_row):end, (1-s_col):end); end IP(IP > Maximum) = Maximum; % The Reset operation NP = (IP + OP)/2; % average with the previous Old Product OP = NP; % get ready for the next comparison end
同樣,提供個編譯好的文件給有興趣研究該算法的朋友看看效果:
http://files.cnblogs.com/Imageshop/Frankle_Mccann_Retinex.zip
***************************作者: laviewpbt 時間: 2013.4.18 聯系QQ: 33184777 轉載請保留本行信息*************************
