OpenCV 图像增强—直方图均衡化和灰度拉伸

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/zhang412yi/article/details/42400779

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;
				}
			}
		}
	}
}


 

 

 

展开阅读全文

没有更多推荐了,返回首页