在限制對比度自適應直方圖均衡化算法原理、實現及效果一文中針對全局直方圖均衡化的一些缺點,提出了分塊的自適應均衡化技術,很好的克服了全局直方圖均衡化的一些缺點,對於圖像增強也有着顯著的作用,我們稍微回顧下CLAHE的算法流程,簡單的可以用下面的過程描述:
for each Tile in Image { Calcuate( HistGram); ClipHistGram(HistGram, ClipLimit); MakeMapping(HistGram); } for each Tile in Image for each Pixel in Tile use bilinear interpolation between four adjacent HistGram info to generate new Pixel
原始的直方圖均衡化算法的核心在上述 MakeMapping(HistGram)函數中得以體現,
void MakeMapping(int* Histgram) { int I, Sum = 0, Amount = 0; for (I = 0; I < 256; I++) Amount += Histgram[I]; for (I = 0; I < 256; I++) { Sum += Histgram[I]; Histgram[I] = Sum * 255/ Amount; // 計算分布 } }
上述Histgram[I] = Sum * 255/ Amount; 一句就是HE算法的核心,就直方圖數據重新分布。
我們回顧一下PS的調整菜單,除了直方圖均衡化是一鍵式菜單(即點擊無可調參數界面,實際上直翻圖均衡化還是有的,在有選區的情況下回彈出一個框),還有另外三個常用的一鍵操作,即:自動色階、自動對比度以及自動顏色。從本質上講,這三個算法同直方圖均衡化一樣,在內部也是一個直方圖重新分布和像素重新映射的過程,因此,如果把這里的MakeMapping函數總映射過程替換他們三者中的某一種會是什么情況和效果呢, 這其實是了解了CLAHE算法的原理后,很自然的能拓寬和聯想到的。
關於自動色階和自動對比度的原理,我在調整圖像- 自動對比度、自動色階算法一文中已經有了較為詳細的實現,而關於自動顏色的原理,目前為止我似乎沒有發現有任何人對其進行了詳細的解釋。我在Imageshop中也只是做了一種簡單的模擬,這里就不提了。
以自動色階為例,上述MakeMapping函數的形式可能如下所示:
void MakeMapping(int* Histgram,float CutLimit=0.01) { int I, Sum = 0, Amount = 0; const int Level = 256; for (I = 0; I < Level; I++) Amount += Histgram[I]; int MinB,MaxB; for (I = 0; I < Level; I++) { Sum = Sum + Histgram[I]; if (Sum >= Amount * CutLimit ) { MinB = I; break; } } Sum = 0; for(I = Level-1; I >= 0; I--) { Sum = Sum +Histgram[I]; if (Sum >= Amount * CutLimit ) { MaxB = I ; break; } } if (MaxB!=MinB) { for (I = 0; I < Level; I++) { if (I<MinB) Histgram[I] =0; else if(I>MaxB) Histgram[I]=255; else Histgram[I] = 255* (I - MinB) / (MaxB - MinB) ; } } else { for (I = 0; I < Level; I++) Histgram[I]=MaxB; // 必須有,不然會有一些圖像平坦的部位效果出錯 } }
注意在這個函數里我增加了CutLimit參數,這個參數名和CLAHE的一樣,實際上是因為自動色階這種工作方式,就是對直方圖的一種裁剪,因此CLAHE算法的ClipHistGram過程就可以舍去了,而把CutLimit作為自動色階的一個調節參數也是順其自然的一個事情了。
在上述代碼代碼中,if (MaxB!=MinB)的判斷主要是防止出現除以0的錯誤,同時在這種情況發生時,必須把直方圖中的所有數據都設置為MaxB(其實這種情況發生時,原始直方圖數據中必然是大部分都等於MaxB,但可能還是有部分是不同的,如果不賦值為MaxB,處理的結果圖像中會出現莫名其妙的紋理圖)。
把上述代碼替換掉CLAHE算法中相應的部分,保持插值等代碼不動,可獲得如下效果:
原圖 塊大小為200,CutLimit =0.01 處理后結果
由上面的圖可以看出,處理前后的增強效果還是很明顯的,整個圖像顯得更清晰。
根據上述代碼分析,這樣處理的效果肯定是原先圖像中的黑的部分更黑,白的部分更白,因此,對比度更加宣明。為了能控制整個對比度調節的程度,我們新增加一個參數,用來調節在最后隱射階段的最大值。我這里做了如下的處理:
void MakeMapping(int* Histgram,float CutLimit=0.01,float Contrast = 1) { int I, Sum = 0, Amount = 0; const int Level = 256; for (I = 0; I < Level; I++) Amount += Histgram[I]; int MinB =0 ,MaxB=255; int Min = 0,Max=255; for (I = 0; I < Level; I++) { if (Histgram[I]!=0) { Min = I ; break; } } for(I = Level-1; I >= 0; I--) { if (Histgram[I]!=0) { Max = I ; break; } } for (I = 0; I < Level; I++) { Sum = Sum + Histgram[I]; if (Sum >= Amount * CutLimit ) { MinB = I; break; } } Sum = 0; for(I = Level-1; I >= 0; I--) { Sum = Sum +Histgram[I]; if (Sum >= Amount * CutLimit ) { MaxB = I ; break; } } int Delta = (Max - Min) * Contrast * 0.5 ; Min = Min - Delta; Max = Max + Delta ; if (Min < 0) Min = 0; if (Max > 255) Max = 255; if (MaxB!=MinB) { for (I = 0; I < Level; I++) { if (I<MinB) Histgram[I] =Min; else if(I>MaxB) Histgram[I]=Max; else Histgram[I] = (Max-Min)* (I - MinB) / (MaxB - MinB) + Min ; } } else { for (I = 0; I < Level; I++) Histgram[I]=MaxB; // 必須有,不然會有一些圖像平坦的部位效果出錯 } }
首先分析獲得原始塊中的最大值和最小值,然后再這個的基礎上按照設定的參數向黑和白兩個方向同等程度擴展,這樣就避免了無論什么情況下的分布都直接擴展到0-255內。有效的抑制了噪音的放大。
修改后,我們看看一些效果:
原圖 CutLimit =0.01,Contrast=1 CutLimit =0.05,Contrast=1
分析:上面這幅圖原始圖像整體就比較亮,因此,在Contrast=1的時候,很多塊調整后的Min=0,Max也等於255了,因此繼續增加Contrast參數,圖像的效果基本沒有什么變化了。而增加CutLimit值使得圖像的映射表由兩個極端向中間靠攏,圖像會稍微顯得濃烈一些。
原圖 CutLimit =0.01,Contrast=1 CutLimit =0.01,Contrast=2.5
而上面這幅圖像,則由於整體比較暗,增加Contrast的效果就比較明顯了,當Contrast=2.5,圖像頂部的一些細節信息也能清晰的表達出來。
另外,分析原始代碼的雙線性插值部分可知,在四周邊緣處,特備是離邊緣小於TileX/2或小於TileY/2的部分,由於其臨近信息的缺失,實際上是沒有進行雙線性插值的,這樣對於部分圖像,邊緣處顯得有點不自然,彌補的方式就是在處理前對圖像進行擴展,分別向四周擴展TileX/2和TileY/2大小,當然擴展部分的數據需要按照鏡像的方式填充數據。
在貼一些這個算法的處理效果:
特別是最后一幅圖,處理的效果都要比我博客中其他的幾種方法來的好,感覺真是帥呆了。
實際中還發現,如果每個塊的大小太小,處理的速度和效果都會有所下降,太大就相當於全局的處理了,因此,一般情況下可取將一副圖平均分成約4*4塊大小的塊大小。同時,調節塊大小時還會出現一些點突然過亮或過暗的現象,這個問題可能會影響一部分圖的效果。
用C寫個DLL,並提供了C#調用的實例:http://files.cnblogs.com/Imageshop/AdaptAutoContrastTest.rar
上圖中通道分離選項可以看成是局部自動色階和自動對比度算法的切換,在勾選通道分離選項時,對於部分圖像會發現有偏色的現象,這個現象在PS中使用自動色階和自動對比度時也會出現。
*********************************作者: laviewpbt 時間: 2013.10.29 聯系QQ: 33184777 轉載請保留本行信息************************