1、直方图均衡化
void cvEqualizeHist( const CvArr* src, CvArr* dst );
用来使灰度图象直方图均衡化,可以将比较淡的图像变换为比较深的图像(即增强图像的亮度及对比度)。
2、灰度拉伸
由于光线原因会造成图像局部过亮或过暗,需要对图像进行拉伸使之覆盖较大的取值区间。使亮的区域更亮,暗的区域更暗,提高图像的对比度,从而使图像边缘明显。灰度拉伸是将灰度图像进行分段性变化,即若原图像f(x,y)的灰度变化区间为[a,b],变换后图像g(x,y)的灰度范围扩展到区间[c,d],可采用下列线性变换来实现:
代码如下:
void stretch(IplImage* src,IplImage* dst,int nMin,int nMax)
{
int low_value=nMin; //拉伸后像素的最小值
int high_value=nMax; //拉伸后像素的最大值
float rate=0; //图像的拉伸率
float stretch_p[256],stretch_p1[256],stretch_num[256];
//清空三个数组,初始化填充数组元素为0
memset(stretch_p,0,sizeof(stretch_p));
memset(stretch_p1,0,sizeof(stretch_p1));
memset(stretch_num,0,sizeof(stretch_num));
//统计图像各个灰度级出现的次数
uchar* srcData=(uchar*)src->imageData;
uchar* dstData=(uchar*)dst->imageData;
int nHeight=src->height;
int nWidth=src->width;
int i,j;
uchar nVal=0;
for (i=0;i<nHeight;i++)
{
for (j=0;j<nWidth;j++)
{
nVal=srcData[i*nWidth+j];
stretch_num[nVal]++;
}
}
//统计各个灰度级出现的概率
for (i=0;i<256;i++)
{
stretch_p[i]=stretch_num[i]/(nHeight*nWidth);
}
//统计各个灰度级的概率和
for (i=0;i<256;i++)
{
for (j=0;j<=i;j++)
{
stretch_p1[i]+=stretch_p[j];
}
}
//计算两个阈值点的值
for (i=0;i<256;i++)
{
if (stretch_p1[i]<0.1) //low_value取值接近于10%的总像素的灰度值
{
low_value=i;
}
if (stretch_p1[i]>0.9) //high_value取值接近于90%的总像素的灰度值
{
high_value=i;
break;
}
}
rate=(float)255/(high_value-low_value+1);
//进行灰度拉伸
for (i=0;i<nHeight;i++)
{
for (j=0;j<nWidth;j++)
{
nVal=srcData[i*nWidth+j];
if (nVal<low_value)
{
dstData[i*nWidth+j]=0;
}
else if (nVal>high_value)
{
dstData[i*nWidth+j]=255;
}
else
{
dstData[i*nWidth+j]=(uchar)((nVal-low_value)*rate+0.5);
if (dstData[i*nWidth+j]>255)
{
dstData[i*nWidth+j]=255;
}
}
}
}
}