直方图均衡化

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

直方图均衡化的处理流程

直方图均衡化处理流程图

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

其中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<uchar>(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<uchar>(i)[j] = (int)Gray_Level_New[(int)Out.ptr<uchar>(i)[j]];
        }
    }

    return Out;

}
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容