直方圖均衡化算法實現

直方圖

直方圖(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):是信息量的度量,其定義爲:

                                wKioL1QoBbWzyk1IAAAcYO8-5EQ815.jpg

其中, pi是符號 i出現的概率。  在圖像中,wKiom1QoBeaT19-8AAAei2E3AtA404.jpgpr是灰度級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來顯示圖片)


wKioL1QoA3KABweyAAXY_lr1bhE981.jpg



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