直方圖均衡化原理與實現

PRO_Z發表於2023-12-01

一 直方圖均衡化的概念

直方圖均衡化(Histogram Equalization)是一種**增強影像對比度**(Image Contrast)的方法,其主要思想是將一副影像的**灰度直方圖分佈**透過**累積分佈函式**變成**近似均勻分佈**(直觀上在某個灰階範圍內畫素值保持一致 ),從而增強影像的對比度。為了將原影像的亮度範圍進行擴充套件, 需要一個對映函式, 將原影像的畫素值均衡對映到新直方圖中。

問題1:為什麼選擇累計分佈函式?

均衡化過程中,必須要保證兩個條件:①畫素無論怎麼對映,一定要保證原來的大小關係不變,較亮的區域,依舊是較亮的,較暗依舊暗,只是對比度增大,絕對不能明暗顛倒;②如果是8點陣圖像,那麼畫素對映函式的值域應在0和255之間的,不能越界。綜合以上兩個條件,累積分佈函式是個好的選擇,因為累積分佈函式是單調增函式(控制大小關係),並且值域是0到1(控制越界問題),所以直方圖均衡化中使用的是累積分佈函式。

問題2:為什麼使用累積分佈函式處理後畫素值會均勻分佈?

對於機率分佈函式和累積分佈函式,前者的二維影像的灰度直方圖是參差不齊的,後者因為人眼視覺系統(HVS),會將小範圍內的畫素值認為是同一個畫素值,即在某個灰階範圍內畫素值保持一致,故後者的二維影像的灰度直方圖呈現均勻分佈;

二 直方圖均衡化的原理

假設影像中畫素的總數是 N,影像的灰度級數是 L,灰度級空間是[0, L-1],用?_?表示第 k 級灰度(第 k 個灰度級,畫素值為 k)在影像內的畫素點個數,那麼該影像中灰度級為?_?(第 k 個灰度級)出現的機率為:

image

根據灰度級機率,對其進行均衡化處理的計算公式為:

image

\[式中,\sum_{j=0}^{k} P_{r}\left(r_{j}\right)表示累計機率,將該值與灰度級的最大值 L-1 相乘即得到均衡化後的新灰度級(畫素值) \]

三 直方圖均衡化的求解過程

求解步驟:

  1. 求輸入影像的灰度直方圖
  2. 對灰度直方圖進行歸一化,即機率直方圖
  3. 求累計機率直方圖(累計分佈函式),記作 Trans
  4. 透過 均衡化原理 將 源輸入影像的畫素值 對映到 均衡化後的影像畫素值中去

參考連結:https://blog.csdn.net/weixin_40163266/article/details/113802909,注:求出Trans後,將影像對映到8位點陣圖(0~255),是 Trans * 255

image

四 直方圖均衡化的程式碼及結果分析

核心程式碼:

def histCalc(img):
    """
    灰度直方圖統計
    :param img: 灰度圖
    :return: 直方圖
    """
    hist = np.zeros(256)
    rows = img.shape[0]
    cols = img.shape[1]
    for i in range(rows):
        for j in range(cols):
            tmp = img[i][j]
            hist[tmp] = hist[tmp] + 1
    print(hist.shape)
    return hist

def histEqualize(img):
    """
    直方圖均衡化
    :param img: 灰度圖
    :return: 均衡化的影像
    """
    hist = histCalc(img)
    imgH, imgW = img.shape[0], img.shape[1]
    allPixel = imgH * imgW

    # 計算累計分佈函式(變換函式)
    trans = hist / allPixel * 255
    for i in range(1, len(trans)):
        trans[i] = trans[i] + trans[i-1]

    # 均衡化後的影像
    imageEqualize = img.copy()
    for i in range(imgH):
        for j in range(imgW):
            imageEqualize[i][j] = trans[img[i][j]]

    return imageEqualize

執行結果:

image

結果分析:輸入影像中沒有較暗、較亮的畫素值,經過均衡化後,輸入影像中的較暗、較亮的影像區域得到了有效改善。

相關文章