直方图均衡化

最近在学习数字图像处理,自己对一些算法做了总结,方便以后查阅。

直方图均衡化的处理流程

直方图均衡化处理流程图

映射方法的函数如下所示:

其中n表示所有像素点的个数,nj表示灰度值为j的像素的个数。Sk为得到的新的灰度级。(原来为0的灰度和L-1的灰度映射完是不会改变的。)

结果对比

直方图分布
直方图均衡化的结果

均衡化后的直方图分布一般都不是均匀的,从上图可以看出均衡化的图像有明显的增强,骨骼的结构更加的清晰,自己写的函数,没有自带的函数效果好,我觉得可能是灰度值为小数的时候,我直接强制类型转化成int型,这中间可能存在一定问题。总体来说,直方图均衡化对于背景和前景都太亮或者太暗的图像非常有用。

核心代码

Mat HistogramEqual(Mat Img){
    Mat Out = Img;
    int ImgSize = Img.cols * Img.rows;  
    double Gray_Level_New[256];         //存放新的灰度级
    int GrayVal_Add[256];               //存放各个灰度值的个数
    double P[256];                      //存放各级灰度值所占的比列 也就是概率


    cvtColor(Out, Out, CV_BGR2GRAY);     

    /*初始化各参数*/
    int idx = 0;
    for (int i = 0; i < 256; i++){
        GrayVal_Add[i] = 0;
        P[i] = 0;
        Gray_Level_New[i] = 0;

    }


    /*统计每个灰度值的个数*/
    for (int i = 0; i < Img.rows; i++)
        for (int j = 0; j < Img.cols; j++){
            GrayVal_Add[Out.ptr(i)[j]] += 1;
        }

    for (int i = 0; i < 256; i++){
        P[i] = (double)GrayVal_Add[i] / ImgSize;
    }


    /*建立新的灰度级别的数组*/
    double sum = 0;
    for (int i = 0; i < 256; i++){

        sum += P[i];
        Gray_Level_New[i] = sum * 255;
    }

    /*结果*/
    for (int i = 0; i < Out.rows; i++){
        for (int j = 0; j < Out.cols; j++){
            Out.ptr(i)[j] = (int)Gray_Level_New[(int)Out.ptr(i)[j]];
        }
    }

    return Out;

}

你可能感兴趣的:(直方图均衡化)