今天自己实现了一下直方图均衡化,但是结果和opencv的直方图均衡化差距较大,还没找到根本原因,找到在下面评论回复
原理都是一样的
1. 计算输入图像的直方图 H
2. 直方图归一化,因此直方块和为255
3. 计算直方图积分:
4. 采用H'作为查询表:dst(x,y)=H'(src(x,y))进行图像变换。
自己写的代码如下:
int IMGHistEqualization(IplImage *src)
{
if(NULL == src)
return -1;
if(src->nChannels!=1 )
{
cout<<"It's not gray image!"<<endl;
return -1;
}
int hist[256]={0};
int Mapping[256]={0};
double phist[256]={0.0};
double histSum[256]={0.0};
int gray = 0;
//记录每一个灰度级的像素点个数
for(int i = 0;i < src->height;i++){
for(int j = 0; j < src->width; j++){
gray = src->imageData[src->widthStep * i + j ];
hist[gray]++;
}
}
//将直方图归一化
for (int i = 0; i <= 255 ;i++)
{
phist [i] = (double) hist[i] / (src->height * src->width*1.0f); //归一化直方图 即每个像素出现概率
}
//并求得累计直方图
for(int i = 0; i<=255;i++)
{
if(i != 0)
{
histSum[i] = histSum[i-1] + phist[i];
}
else
{
histSum[i] = phist[i];
}
}
//求直方图映射关系
for (int i = 0; i< 256; i++)
{
Mapping[i] = (int)(255.0f * histSum[i] + 0.5f);
}
//均衡化
for(int y = 0; y < src->height; y++)
{
for(int x = 0; x < src->width;x++)
{
gray = src->imageData[src->widthStep * y + x ];
src->imageData[src->widthStep * y + x ] = Mapping[gray]; //根据映射关系实现均衡化
}
}
return 0;
}
opencv直方图均衡化
EqualizeHist
灰度图象直方图均衡化
void cvEqualizeHist( const CvArr* src, CvArr* dst );
src
输入的 8-比特 单信道图像
dst
输出的图像与输入图像大小与数据类型相同