直方圖
直方圖(histogram)是灰度級的函數,它表示圖像中具有每種灰度級的像素的個數,
反映原圖中各種灰度值分佈的情況。
如下圖所示,灰度直方圖的橫座標是灰度級,縱座標是該灰度級出現的頻率,是圖像的最基本的統計特徵。
上面的是標準直方圖
灰度統計累計直方圖:
H(k)= ∑ni(i<=k)
累積直方圖中第k列的高度是圖像中所有灰度值<=k的像素的個數
灰度直方圖的求取算法實現
void GetHistogram(BYTE *image_Src, int width, int height, unsigned long *histogram) { int pixelCount = width*height;//imageSize->pixelCount memset(histogram, 0, 256*4);//注意最後一個參數是數組的大小(單位是字節) for (int i = 0; i <= pixelCount - 1; ++i) { int gray = image_Src[0]; histogram[gray]++; //下一個像素 image_Src+=1; } }
直方圖的特點
直方圖具有很多的優點,直方圖能反映圖像的概貌,
圖像中有幾類目標,目標和背景的分佈如何;
通過直方圖可以直接計算圖像中的最大亮度、最小亮度、平均亮度、對比度以及中間亮度等。
使用直方圖可以完成圖像分割、目標檢索等。因爲不同的目標具有不同的顏色分佈。使用歸一化直方圖作目標匹配,還不易受到目標翻轉和目標大小變化的影響。
在圖像查詢的系統中,直方圖有很大的應用,用它存儲目標的特徵佔有空間小,且執行速度快。
其缺點:因其沒有記錄位置信息,不同的圖像會具有相同或相近的直方圖。一幅圖像旋轉、翻轉後的直方圖是相同的;放大、縮小後的直方是相近的。
直方圖均衡化
原理
爲了增強圖像整體的對比效果,增加灰度值的動態範圍
由圖像點運算可知,圖像增強的公式可以表示爲
G(x,y)=F(g(x,y))
這裏,由於要增強對比效果,所以
這裏假設原圖灰度級範圍位爲採用歸一化的[0,1]
F()在整個灰度級範圍[0,1]內是遞增函數(因爲要增強對比)
F()的值域也是[0,1]
可以證明累計分佈函數滿足上面的變換函數要求,而圖像中,這個累計分佈函數,就是原始圖像的累計直方圖。
F()通常都是作爲查找表LUT出現的,因爲是離散的,所以累計直方圖也是可以作爲LUT出現
實際上:累計分佈直方圖作爲圖像變換函數(本質爲LUT)。從而將增強了原圖像的對比效果。而通常圖像變換函數是離散的,通過LUT實現,所以通過累計分佈直方圖作就可以實現直方圖均衡化。
也可以用熵的原理來解釋均衡化原理:
熵(Entropy):是信息量的度量,其定義爲:
其中, pi是符號 i出現的概率。 在圖像中,pr是灰度級r 出現的概率。
可以證明,當p0=p1=p2=…=p255=1/256時,H取最大值,即圖像信息量最大。
根據熵理論可知,直方圖中,當H[0],H[1]…,H[n-1]相等時,圖像信息量最大-》均衡化的目的是使每個Hi都相等,即把原始圖的直方圖變換爲均勻分佈的形式,這樣就增加了象素值的範圍,增強了圖像的對比效果。
對於熵這個概念,我也是費了好大的勁才大概能夠明白他的意思:
熵越大,系統的不確定性越大,系統越混亂,從而信息量也就越大。
對於單個信息,可以理解爲發生的概率越小 ,熵越大
對於一個系統,如果系統由多個部分組成,則可以理解爲各個部分發生概率基本相等時熵最大
關於熵的概念,大家可以參考吳軍老師的《數學之美》中關於熵的解釋,比較通俗易懂。
直方圖均衡化算法實現
void GetHistogramEqualize(BYTE *image_Src,BYTE *image_Dst, int width, int height) { //-------step 1.求灰度直方圖 unsigned long historgam[256]; GetHistogram(image_Src, width, height, historgam); //------step 2.求累計分佈直方圖(灰度變換函數,LUT) //累計分佈直方圖符合增強對比度函數的要求 int LUT[256]; LUT[0] = historgam[0]; int sum = historgam[0]; for (int i = 1; i <= 255; ++i) { sum += historgam[i]; LUT[i] =255* sum / (width*height); } //----step 3.對原圖像做圖像增強 int pixelCount = width*height; for (int i = 0; i <= pixelCount - 1; ++i) { int gray = image_Src[i]; image_Dst[i] = LUT[gray]; } }
效果圖(藉助了Opencv來顯示圖片)