折腾了一天,终于搞明白原理,把程序也调通了,真是惭愧,基础实在太差。
直方图均衡化的原理很简单,利用概率中的累积函数的性质,达到映射的目的,改变原图像的灰度分布,使之近似的均匀。
这是我在网上找的:
这是我的程序:
float p[256];
float c[256];
Uint16 *ps,*tmp;
ps=(Uint16*)memaddr;//取一个象素(Cb/Y),所以Y为&0xFF00;
//初始化数组
for(i=0;i<256;i++)
{
Dia[i]=0;
p[i]=0.0f;
c[i]=0.0f;
}
for(i=0;i<480;i++)
{
for(j=0;j<720;j++)
{
gray=((*ps)&0xFF00)>>8;//取出当前象素Y值,0~255;
Dia[gray]=(Dia[gray]+1);//该级灰度值加一
//*ps=((*ps)&0xff00)+0x80;//二值化
ps++;
}
}
for(i=0;i<256;i++)
{
p[i]=(float)Dia[i]/(480*720);//p[]是归一化直方图
}
for(i=0;i<256;i++)
{
for(j=0;j
{
c[i]+=p[j];//c[]是累积归一化直方图
}
}
tmp=(Uint16*)memaddr;//取一个象素地址
ps=tmp;
for(i=0;i<480;i++)
{
for(j=0;j<720;j++)
{
gray=((*ps)&0xFF00)>>8;//取出当前象素Y值,0~255;
*ps= ((Uint8)(c[gray]*255)<<8)+0x80;
ps++;
}
}
主要分三步:
1. 求出原图像的灰度直方图Dia[];
2. 求原图像的累积直方图c[];
3. 把原图像的像素值映射为新的像素值,ps是指向原图像的指针。按照公式,原像素值通过原图像的CDF映射成为新像素值,由于C[]范围[0,1],而灰度级是255,故应乘以255转化为像素值。
另:
图像存储方式Y-Cb-Y-Cr,取Y做变换, {MOD}差设为0x80,不然颜 {MOD}会有异常。