直方图均衡化

概念:通过拉伸像素强度分布范围来增强图像对比度的一种方法,如下图,将左边直方图的中间的一些强度值拉伸,对绿色椭圆部分应用均衡化后得到右边的直方图,要想把左边的直方图映射到另一个直方图,需使用一个累计分布函数

直方图均衡化_第1张图片
直方图拉伸.png

步骤:
1、统计像素灰度的个数,范围在0-255之间,所以数组长度可以取266
2、计算像素灰度密度
3、使用累积分布函数计算右边的直方图
4、使用最大值255进行归一化
5、对原图像映射赋值灰度值

代码

typedef struct
{
    int mSize;//图像大小
    int mChannels;//通道数
    int mDepth;//
    int mType;
    int mCol;
    int mRow;
    unsigned char *mData;
} V_Image;

void Histogram_equalization(V_Image** img)
{
    float *pixelNum=(float *) calloc(256,sizeof(float));
    float *pixelCumu=(float *) calloc(256,sizeof(float));
    int index,row,col;
    //初始化数组为0
    for(index=0; index<256; index++)
    {
        pixelNum[index]=0;
        pixelCumu[index]=0;
    }
    //统计像素灰度个数
    for(row=0; row<(*img)->mRow; row++ )
    {
        for(col=0; col<(*img)->mCol; col++ )
        {
            pixelNum[(*img)->mData[row*((*img)->mCol)+col]+1]++;
        }
    }

    //计算像素灰度密度
    for(index=0; index<256; index++)
    {
        pixelNum[index]=pixelNum[index]/(((*img)->mRow)*((*img)->mCol)*1);
    }

    //计算累计直方图分布
    for(index=0; index<256; index++)
    {
        if(index==0)
            pixelCumu[index]=pixelNum[index];
        else
            pixelCumu[index]=pixelCumu[index-1]+pixelNum[index];
    }
    //累计分布取整
    for(index=0; index<256; index++)
    {
        pixelCumu[index]=ceil(255*pixelCumu[index]);
    }
    //对图像灰度值均衡化
    for(row=0; row<(*img)->mRow; row++ )
    {
        for(col=0; col<(*img)->mCol; col++ )
        {
            (*img)->mData[row*((*img)->mCol)+col]=pixelCumu[(*img)->mData[row*((*img)->mCol)+col]];
        }
    }
}

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