【數字圖像處理】灰度直方圖、直方圖均衡化、直方圖規定化

  • 2019 年 10 月 3 日
  • 筆記

 

 

灰度直方圖

  一幅圖像由不同灰度值的像素組成,圖像中灰度的分佈情況是該圖像的一個重要特徵。圖像的灰度直方圖就描述了圖像中灰度分佈情況,能夠很直觀的展示出圖像中各個灰度級所佔的多少。
圖像的灰度直方圖是灰度級的函數,描述的是圖像中具有該灰度級的像素的個數:其中,橫坐標是灰度級,縱坐標是該灰度級出現的頻率。

灰度直方圖的計算公式如下:

p(rk)=nk/MN

其中,rkrk是像素的灰度級,nknk是具有灰度rkrk的像素的個數,MNMN是圖像中總的像素個數。

 

直方圖均衡化 Histogram Equalization

假如圖像的灰度分佈不均勻,其灰度分佈集中在較窄的範圍內,使圖像的細節不夠清晰,對比度較低。通常採用直方圖均衡化直方圖規定化兩種變換,使圖像的灰度範圍拉開或使灰度均勻分佈,從而增大反差,使圖像細節清晰,以達到增強的目的。
直方圖均衡化,對圖像進行非線性拉伸,重新分配圖像的灰度值,使一定範圍內圖像的灰度值大致相等。這樣,原來直方圖中間的峰值部分對比度得到增強,而兩側的谷底部分對比度降低,輸出圖像的直方圖是一個較為平坦的直方圖。

均衡化算法

直方圖的均衡化實際也是一種灰度的變換過程,將當前的灰度分佈通過一個變換函數,變換為範圍更寬、灰度分佈更均勻的圖像。也就是將原圖像的直方圖修改為在整個灰度區間內大致均勻分佈,因此擴大了圖像的動態範圍,增強圖像的對比度。通常均衡化選擇的變換函數是灰度的累積概率,直方圖均衡化算法的步驟:

  • 計算原圖像的灰度直方圖 P(Sk)=nknP(Sk)=nkn,其中nn為像素總數,nknk為灰度級SkSk的像素個數
  • 計算原始圖像的累積直方圖 CDF(Sk)=i=0knin=i=0kPs(Si)CDF(Sk)=∑i=0knin=∑i=0kPs(Si)
  • Dj=LCDF(Si)Dj=L⋅CDF(Si),其中 DjDj是目的圖像的像素,CDF(Si)CDF(Si)是源圖像灰度為i的累積分佈,L是圖像中最大灰度級(灰度圖為255)

灰度直方圖均衡化實現的步驟

1.統計灰度級中每個像素在整幅圖像中的個數

2.計算每個灰度級占圖像中的概率分佈

3.計算累計分佈概率

4.計算均衡化之後的灰度值

5.映射回原來像素的坐標的像素值

示例說明

來看看通過上述步驟怎樣實現的拉伸。假設有如下圖像:

得圖像的統計信息如下圖所示,並根據統計信息完成灰度值映射:

映射後的圖像如下所示:

灰度直方圖均衡化實現

            //img_size為圖像大小              //Image_Use為圖像數組
            //Use_ROWS為行,Use_Line為列
            float img_size = Use_ROWS * Use_Line * 1.0; int count_data[256],huidu_data[256]; //計數統計、均衡化的灰度值 float midu_data[256],leijimidu_data[256]; //概率密度、累計概率密度             //數組初始化 memset(count_data, 0, sizeof(count_data)); memset(midu_data, 0.0, sizeof(midu_data)); memset(leijimidu_data, 0.0, sizeof(leijimidu_data)); memset(huidu_data, 0.0, sizeof(huidu_data)); //1.統計灰度級中每個像素在整幅圖像中的個數 for(int i = 0; i < Use_ROWS; i++) { for(int j = 0; j < Use_Line; j++) { count_data[Image_Use[i][j]]++; } } //2.計算每個灰度級占圖像中的概率分佈 for(int i = 0; i < 256; i++) { midu_data[i] = count_data[i]/ img_size; } //3.計算累計分佈概率 leijimidu_data[0] = midu_data[0]; for(int i = 1; i < 256; i++) { leijimidu_data[i] = midu_data[i]+leijimidu_data[i-1]; } //4.計算均衡化之後的灰度值 for(int i =0; i <256; i++) { huidu_data[i] = (int)(255 * leijimidu_data[i]); } //5.映射回原來像素的坐標的像素值 for(int i = 0; i < Use_ROWS; i++) { for(int j = 0; j < Use_Line; j++) { Image_Use[i][j] = huidu_data[Image_Use[i][j]]; } }

 

 

 

 原始圖像:

 

 

 

 

 直方圖均衡化後的圖像:

 

 

   

直方圖規定化

參考:

圖像處理基礎(8):圖像的灰度直方圖、直方圖均衡化、直方圖規定化(匹配)