直方图均衡化---算法分析与编程实现(opencv与c++)

版权声明:本文为博主原创文章,转载请注明出处 https://blog.csdn.net/thecentry。 https://blog.csdn.net/thecentry/article/details/80348625

图像增强------对比度增强。对比度增强可以分为(1)直接对比度增强;(2)间接对比度增强。直接对比度增强可以分为线性变换,分线段线性拉伸,以及指数拉伸与对数拉升。间接对比度增强主要就要直方图均衡化。

直方图均衡化的主要思想是:把原始图像的灰度直方图从比较集中的某个灰度区间变成在全部灰度范围内的均匀分布。直方图均衡化就是对图像进行非线性拉伸,重新分配图像像素值,使一定灰度范围内的像素数量大致相同。直方图均衡化就是把给定图像的直方图分布改变成“均匀”分布直方图分布。

算法过程:

(1)根据图像灰度计算灰度密度函数PDF.

(2)计算积累分布函数CDF。(cumulative distribution function)

(3)将CDF归一化到原图取值范围[0,255]。

(4)将CDF四色五入取整,得到灰度转换函数SK=T(RK)。

(5)把原图像素点值为rk的变换为sk。

PDF的算法:gk = EQ(fk) = (ni/n) = pf(fi) ,ni表示第K个灰度级的像素点个数。n表示图像的像素点总数。

CDF的算法:

灰度转化函数:sk=255*ck。

利用opencv实现如下:

void CMyTestDlg::OnEqualizeHist()
{
	std::vector<Mat>splitBGR(src.channels());
	split(src, splitBGR);//图像通道分离
	for (int i = 0; i < src.channels(); i++)
	{
		equalizeHist(splitBGR[i], splitBGR[i]);//图像灰度均衡化
	}
	Mat dst;
	merge(splitBGR, dst);
	ShowPicture(dst);
}

效果图:


左边为原图,右边为均衡化效果。

c++实现算法:

/*************************************************************************
 * 函数名称:
 *   InteEqualize()
 * 参数:
 *   LPSTR lpDIBBits    - 指向源DIB图像指针
 *   LONG  lWidth       - 源图像宽度(象素数)
 *   LONG  lHeight      - 源图像高度(象素数)
 * 返回值:
 *   BOOL               - 成功返回TRUE,否则返回FALSE。
 * 说明:
 *   该函数用来对图像进行直方图均衡。
 ************************************************************************/
BOOL CDibImage::InteEqualize(LPSTR lpDIBBits, LONG lWidth, LONG lHeight)
{	
	unsigned char*	lpSrc;				// 指向源图像的指针	
	LONG	lTemp;						// 临时变量	
	LONG	i;							// 循环变量
	LONG	j;	
	BYTE	bMap[256];					// 灰度映射表	
	LONG	lCount[256];				// 灰度映射表
	LONG	lLineBytes;					// 图像每行的字节数
		
	lLineBytes = WIDTHBYTES(lWidth * 8);// 计算图像每行的字节数


	if (Nbb != NULL)
	{
		delete[] Nbb;
		Nbb = NULL;
	}
	Nbb = new char[lLineBytes * lHeight + 1];
	memcpy(Nbb, lpDIBBits, lLineBytes * lHeight);

		
	for (i = 0; i < 256; i ++)			// 重置计数为0
	{
		lCount[i] = 0;
	}
	
	// 计算各个灰度值的计数
	for (i = 0; i < lHeight; i ++)
	{
		for (j = 0; j < lWidth; j ++)
		{
			lpSrc = (unsigned char *)lpDIBBits + lLineBytes * i + j;
			lCount[*(lpSrc)]++;
		}
	}
	
	// 计算灰度映射表
	for (i = 0; i < 256; i++)
	{
		lTemp = 0;		
		for (j = 0; j <= i ; j++)
		{
			lTemp += lCount[j];
		}
		
		// 计算对应的新灰度值
		bMap[i] = (BYTE) (lTemp * 255 / lHeight / lWidth);
	}
		
	for(i = 0; i < lHeight; i++)			// 每行
	{
		for(j = 0; j < lWidth; j++)			// 每列
		{
			// 指向DIB第i行,第j个象素的指针
			lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - i) + j;			
			// 计算新的灰度值
			*lpSrc = bMap[*lpSrc];
		}
	}
	
	return TRUE;
}

效果图:


右图为原图,左图为灰度均衡化后的图片。


阅读更多
想对作者说点什么?

博主推荐

换一批

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