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