直方图均衡化
如果一副图像的像素占有很多的灰度级而且分布均匀,那么这样的图像往往有高对比度和多变的灰度色调。直方图均衡化就是一种能仅靠输入图像直方图信息自动达到这种效果的变换函数。它的基本思想是对图像中像素个数多的灰度级进行展宽,而对图像中像素个数少的灰度进行压缩,从而扩展像原取值的动态范围,提高了对比度和灰度色调的变化,使图像更加清晰。
基本思想
直方图均衡化处理的“中心思想”是把原始图像的灰度直方图从比较集中的某个灰度区间变成在全部灰度范围内的均匀分布。直方图均衡化就是对图像进行非线性拉伸,重新分配图像像素值,使一定灰度范围内的像素数量大致相同。直方图均衡化就是把给定图像的直方图分布改变成“均匀”分布直方图分布。
直方图均衡化的基本思想是把原始图的直方图变换为均匀分布的形式,这样就增加了象素灰度值的动态范围从而可达到增强图像整体对比度的效果。设原始图像在(x,y)处的灰度为f,而改变后的图像为g,则对图像增强的方法可表述为将在(x,y)处的灰度f映射为g。在灰度直方图均衡化处理中对图像的映射函数可定义为:g=EQ(f),这个映射函数EQ(f)必须满足两个条件(其中L为图像的灰度级数):
(1)EQ(f)在0≤f≤L-1范围内是一个单值单增函数。这是为了保证增强处理没有打乱原始图像的灰度排列次序,原图各灰度级在变换后仍保持从黑到白(或从白到黑)的排列。
(2)对于0≤f≤L-1有0≤g≤L-1,这个条件保证了变换前后灰度值动态范围的一致性。
累积分布函数(cumulativedistributionfunction,CDF)即可以满足上述两个条件,并且通过该函数可以完成将原图像f的分布转换成g的均匀分布。此时的直方图均衡化映射函数为:
=EQ()=(ni/n)=pf(
),
(k=0,1,2,……,L-1)
上述求和区间为0到k,根据该方程可以由源图像的各像素灰度值直接得到直方图均衡化后各像素的灰度值。在实际处理变换时,一般先对原始图像的灰度情况进行统计分析,并计算出原始直方图分布,然后根据计算出的累计直方图分布求出
到
的灰度映射关系。在重复上述步骤得到源图像所有灰度级到目标图像灰度级的映射关系后,按照这个映射关系对源图像各点像素进行灰度转换,即可完成对源图的直方图均衡化。
示例程序
程序:
//锁定DIB并返回指向DIB的指针
LPSTRlpDIB=(LPSTR)::GlobalLock((HGLOBAL)hDIB);
//找到DIB图像象素起始位置并返回指向DIB象素指针
LPSTRlpDIBBits=m_clsDIB.FindDIBBits(lpDIB);
//获取DIB的宽度
LONGlWidth=m_clsDIB.DIBWidth(lpDIB);
//获取DIB的高度
LONGlHeight=m_clsDIB.DIBHeight(lpDIB);
for(i=0;i\u003clHeight;i++)//对各像素进行灰度转换
{
for(j=0;j\u003clWidth*3;j++)
{
//对各像素进行灰度统计
unsignedcharR=*((unsignedchar*)lpDIBBits+lWidth*3*i+j);
nNs_R[R]++;j++;
unsignedcharG=*((unsignedchar*)lpDIBBits+lWidth*3*i+j);
nNs_G[G]++;j++;
unsignedcharB=*((unsignedchar*)lpDIBBits+lWidth*3*i+j);
nNs_B[B]++;
}
}
for(i=0;i\u003c256;i++)//计算灰度分布密度
{
fPs_R[i]=nNs_R[i]/(lHeight*lWidth*1.0f);
fPs_G[i]=nNs_G[i]/(lHeight*lWidth*1.0f);
fPs_B[i]=nNs_B[i]/(lHeight*lWidth*1.0f);
}
for(i=0;i\u003c256;i++)
{
//计算累计直方图分布
if(i==0)
{
temp_r=fPs_R;
temp_g=fPs_G;
temp_b=fPs_B;
}
else
{
temp_r[i]=temp_r[i-1]+fPs_R[i];
temp_g[i]=temp_g[i-1]+fPs_G[i];
temp_b[i]=temp_b[i-1]+fPs_B[i];
}
//累计分布取整,nNs_R[]、nNs_G[]、nNs_B[]保存有计算出来的灰度映射关系
nNs_R[i]=(int)(255.0f*temp_r[i]+0.5f);
nNs_G[i]=(int)(255.0f*temp_g[i]+0.5f);
nNs_B[i]=(int)(255.0f*temp_b[i]+0.5f);
}
for(i=0;i\u003clHeight;i++)
{
for(j=0;j\u003clWidth*3;j++)
{
//对R分量进行灰度映射(均衡化)
unsignedcharR=*((unsignedchar*)lpDIBBits+lWidth*3*i+j);
*((unsignedchar*)lpDIBBits+lWidth*3*i+j)=nNs_R[R];
j++;
//对G分量进行灰度映射(均衡化)
unsignedcharG=*((unsignedchar*)lpDIBBits+lWidth*3*i+j);
*((unsignedchar*)lpDIBBits+lWidth*3*i+j)=nNs_G[G];
j++;
//对B分量进行灰度映射(均衡化)
unsignedcharB=*((unsignedchar*)lpDIBBits+lWidth*3*i+j);
*((unsignedchar*)lpDIBBits+lWidth*3*i+j)=nNs_B[B];
}
}
基本概述
这种方法通常用来增加许多图像的全局对比度,尤其是当图像的有用数据的对比度相当接近的时候。通过这种方法,亮度可以更好地在直方图上分布。这样就可以用于增强局部的对比度而不影响整体的对比度,直方图均衡化通过有效地扩展常用的亮度来实现这种功能。
这种方法对于背景和前景都太亮或者太暗的图像非常有用,这种方法尤其是可以带来X光图像中更好的骨骼结构显示以及曝光过度或者曝光不足照片中更好的细节。这种方法的一个主要优势是它是一个相当直观的技术并且是可逆操作,如果已知均衡化函数,那么就可以恢复原始的直方图,并且计算量也不大。这种方法的一个缺点是它对处理的数据不加选择,它可能会增加背景噪声的对比度并且降低有用信号的对比度。
参考资料
Warning: Invalid argument supplied for foreach() in /www/wwwroot/6gwu.com/id.php on line 283