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

图像增强------对比度增强。对比度增强可以分为(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;
}

效果图:


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


  • 5
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值