數字圖像處理之圖像直方圖

圖像直方圖反映了圖像像素分佈的統計特性,是圖像處理中簡單有效的工具。本文主要包括圖像直方圖計算,直方圖均衡和直方圖規定化三個部分。

圖像直方圖計算

圖像灰度直方圖:
P(r)=nr/(MN)
上式表示每一個灰度級像素的個數與圖像總像素個數的比值。


直方圖均衡化

直方圖均衡也是很常用的方法,圖像直方圖均衡採用累計分佈函數:
s=f(r)=k0P(r)dr


直方圖規定化

直方圖規定化也叫直方圖匹配,讓原圖像的像素分佈與規定圖像的像素分佈保持一致。
1. s=T(r) ,原圖直方圖變換
2. u=G(z) ,規定圖直方圖變換
3. s=u ,所以z=G1(u)=G1(s)
映射可以採用SML映射或者GML映射

代碼示例

採用opencv3,爲了熟悉原理就不調用opencv自帶的函數了。
1. 直方圖計算

//計算圖像直方圖
void Fun1::CalHistImg(Mat img, double* HistImg)
{
    int size_rows = img.rows;
    int size_cols = img.cols;

    for (int i = 0; i < size_rows; i++)
    {
        uchar* Imgdata = img.ptr<uchar>(i);
        for (int j = 0; j < size_cols; j++)
        {
            HistImg[Imgdata[j]]++;//累加
        }
    }

    for (int i = 0; i < 256; i++)
    {
        HistImg[i] = HistImg[i] / (size_rows*size_cols);//歸一化
    }
}
  1. 直方圖均衡化
//圖像直方圖均衡化
void Fun1::Histeq(Mat& img)
{
    double hist_temp[256] = { 0 };
    CalHistImg(img, hist_temp);

    int size_rows = img.rows;
    int size_cols = img.cols;

    for (int i = 0; i < size_rows; i++)
    {
        uchar* Imgdata = img.ptr<uchar>(i);
        for (int j = 0; j < size_cols; j++)
        {
            uchar gray = Imgdata[j];
            double temp_value = 0;
            for (int k = 0; k < gray; k++)
            {
                temp_value += hist_temp[k];
            }
            int target = 0;
            target = 255 * temp_value;

            if (target > 255)
                target = 255;

            Imgdata[j] = target;
        }
    }
}
  1. 直方圖規定化
//直方圖匹配
void Fun1::HistImgMatch(Mat & src, Mat & matchimg)
{
    int size_rows = src.rows;
    int size_cols = src.cols;

    double srchist[256] = { 0 };
    double matchhist[256] = { 0 };

    CalHistImg(src, srchist);
    CalHistImg(matchimg, matchhist);

    //原圖累計分佈直方圖
    double inc_srchist[256] = { 0 };
    double temp = 0;
    for (int i = 0; i < 256; i++)
    {
        temp += srchist[i];
        inc_srchist[i] = temp;
    }

    //標準圖累計分佈直方圖
    double inc_matchhist[256] = { 0 };
    temp = 0;
    for (int i = 0; i < 256; i++)
    {
        temp += matchhist[i];
        inc_matchhist[i] = temp;
    }

    //單映射關係
    int SML[256] = { 0 };
    for (int i = 0; i < 256; i++)
    {
        double minvalue = 1000;
        double orig_value = inc_srchist[i];
        for (int j = 0; j < 256; j++)
        {
            double stan_value = inc_matchhist[j];
            double srcmin = fabs(stan_value - orig_value);
            if (srcmin < minvalue)
            {
                minvalue = srcmin;
                SML[i] = j;
            }
        }
    }

    for (int i = 0; i < size_rows; i++)
    {
        uchar* Imgdata = src.ptr<uchar>(i);
        for (int j = 0; j < size_cols; j++)
        {
            uchar gray = Imgdata[j];
            Imgdata[j] = SML[gray];
        }
    }
}

原圖:
這裏寫圖片描述


直方圖均衡化:
這裏寫圖片描述


直方圖匹配:(規定圖採用了直方圖均衡化後的圖)
這裏寫圖片描述


這裏寫圖片描述
這裏寫圖片描述
這裏寫圖片描述


上訴3個圖分別是原圖的直方圖,均衡化後的直方圖及規定化後的直方圖。

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