1、直方图均衡化
void cvEqualizeHist( const CvArr* src, CvArr* dst );
用来使灰度图象直方图均衡化,可以将比较淡的图像变换为比较深的图像(即增强图像的亮度及对比度)。
2、灰度拉伸
由于光线原因会造成图像局部过亮或过暗,需要对图像进行拉伸使之覆盖较大的取值区间。使亮的区域更亮,暗的区域更暗,提高图像的对比度,从而使图像边缘明显。灰度拉伸是将灰度图像进行分段性变化,即若原图像f(x,y)的灰度变化区间为[a,b],变换后图像g(x,y)的灰度范围扩展到区间[c,d],可采用下列线性变换来实现:
代码入下:(传入的参数必须是单通道的图像)
void Ctry::stretch(IplImage* src, IplImage* dst)
{
int low_value; //拉伸后像素的最小值
int high_value; //拉伸后像素的最大值
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));
int nHeight = src->height;
int nWidth = src->width;
int i, j;
for (i = 0; i<nHeight; i++)
{
for (j = 0; j<nWidth; j++)
{
double pixel0 = cvGetReal2D(src, i, j);
int pixel =(int) pixel0;
stretch_num[pixel]++;
}
}
//统计各个灰度级出现的概率
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++)
{
int pixel = cvGetReal2D(src, i, j);
if (pixel<low_value)
{
cvSetReal2D(dst, i, j, 0);
}
else if (pixel>high_value)
{
cvSetReal2D(dst, i, j,255);
}
else
{
double temp = (pixel - low_value)*rate + 0.5;
cvSetReal2D(dst, i, j, temp);
if (temp>255)
{
cvSetReal2D(dst , i, j, 255);
}
}
}
}
}
效果图: