圖像處理之直方圖均衡化及C++實現


1. 背景

直方圖均衡化在圖像增強方面有着很重要的應用。一些拍攝得到的圖片,我們從其直方圖可以看出,它的分布是集中於某些灰度區間,這導致人在視覺上感覺這張圖的對比度不高。所以,對於這類圖像,我們可以通過直方圖均衡技術,將圖像的灰度分布變得較為均勻,從而使得圖像對比度增大,視覺效果更佳。

在這里插入圖片描述

2. 原理

直方圖均衡化的作用是圖像增強。

有兩個問題比較難懂,一是為什么要選用累積分布函數,二是為什么使用累積分布函數處理后像素值會均勻分布。

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

第二個問題。累積分布函數具有一些好的性質,那么如何運用累積分布函數使得直方圖均衡化?比較概率分布函數和累積分布函數,前者的二維圖像是參差不齊的,后者是單調遞增的。直方圖均衡化過程中,映射方法是

在這里插入圖片描述
其中,n是圖像中像素的總和,$n_k$是當前灰度級的像素個數,L是圖像中可能的灰度級總數。

來看看通過上述公式怎樣實現的拉伸。假設有如下圖像:
來看看通過上述公式怎樣實現的拉伸。假設有如下圖像:
得圖像的統計信息如下圖所示,並根據統計信息完成灰度值映射:
在這里插入圖片描述
映射后的圖像如下所示:
在這里插入圖片描述

3. C++實現

直方圖均衡化的代碼實現有以下幾個步驟:

  1. 遍歷全圖,先統計每個灰度級下的像素點個數(為此我們開辟了256大小的數組);
  2. 計算每個灰度級的像素點占總像素的點的比例;
  3. 按照第二步求出的比例重新計算每個灰度級下的新的灰度值,即均衡化;
  4. 依照新的灰度值表遍歷更新圖像的灰度值。
int gray[256] = { 0 };  //記錄每個灰度級別下的像素個數
double gray_prob[256] = { 0 };  //記錄灰度分布密度
double gray_distribution[256] = { 0 };  //記錄累計密度
int gray_equal[256] = { 0 };  //均衡化后的灰度值

int gray_sum = 0;  //像素總數

Mat equalize_hist(Mat& input)
{
    Mat output = input.clone();
    gray_sum = input.cols * input.rows;

    //統計每個灰度下的像素個數
    for (int i = 0; i < input.rows; i++)
    {
        uchar* p = input.ptr<uchar>(i);
        for (int j = 0; j < input.cols; j++)
        {
            int vaule = p[j];
            gray[vaule]++;
        }
    }

  
    //統計灰度頻率
    for (int i = 0; i < 256; i++)
    {
        gray_prob[i] = ((double)gray[i] / gray_sum);
    }

    //計算累計密度
    gray_distribution[0] = gray_prob[0];
    for (int i = 1; i < 256; i++)
    {
        gray_distribution[i] = gray_distribution[i-1] +gray_prob[i];
    }

    //重新計算均衡化后的灰度值,四舍五入。參考公式:(N-1)*T+0.5
    for (int i = 0; i < 256; i++)
    {
        gray_equal[i] = (uchar)(255 * gray_distribution[i] + 0.5);
    }


    //直方圖均衡化,更新原圖每個點的像素值
    for (int i = 0; i < output.rows; i++)
    {
        uchar* p = output.ptr<uchar>(i);
        for (int j = 0; j < output.cols; j++)
        {
            p[j] = gray_equal[p[j]];
        }
    }

    return output;
}

4. 最后


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM