数字图像处理之图像直方图

图像直方图反映了图像像素分布的统计特性,是图像处理中简单有效的工具。本文主要包括图像直方图计算,直方图均衡和直方图规定化三个部分。

图像直方图计算

图像灰度直方图:
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];
        }
    }
}

原图:
数字图像处理之图像直方图_第1张图片


直方图均衡化:
数字图像处理之图像直方图_第2张图片


直方图匹配:(规定图采用了直方图均衡化后的图)
数字图像处理之图像直方图_第3张图片


数字图像处理之图像直方图_第4张图片
数字图像处理之图像直方图_第5张图片
数字图像处理之图像直方图_第6张图片


上诉3个图分别是原图的直方图,均衡化后的直方图及规定化后的直方图。

你可能感兴趣的:(opencv,图像处理)