C++数字图像处理(3)—直方图均衡化

1、算法原理

直方图均衡化是一种非线性的灰度变换,主要是用来拉伸图像的灰度动态范围,提高图像对比度。直方图均衡化的具体数学推导这里不做介绍,这里,我们只用“白话”的形式介绍一下累积分布函数(CDF)这个概念。说到分布,肯定就会牵涉到随机变量。假如,我们把一幅图像的像素值看做是随机变量,那么为了描述整副图像的灰度的分布情况,我们可以将每个灰度等级在图像中出现的次数统计出来(即直方图),将直方图除以像素总个数,即可得到每个灰度等级出现的概率(归一化直方图),也就是随机变量的分布函数。回过头来,累积分布函数中分布函数就理解了,那么,累积就好理解了。累积即累加,在得到归一化直方图后,累积分布函数即为归一化直方图的累加和。

2、算法实现

(1)、直方图统计

//函数名:HistogramEqual
//功能:直方图均衡化功能实现
//参数:
//pInputOutputData : 输入输出图像数据指针
//nWidth:图像宽度
//nHeight:图像高度
//备注:该函数仅支持8位单通道灰度图像进行处理。
void HistogramEqual(unsigned char* pInputOutputData, int nWidth, int nHeight)
{
	const int GRAY8_MAX = 256;

	//统计直方图
	float szHistogram[GRAY8_MAX] = {0.0};
	for (int m = 0; m < nWidth*nHeight; m++)
		szHistogram[pInputOutputData[m]]++;

(2)、直方图归一化

	//直方图归一化
	float fNormal = 1.0f / (nWidth * nHeight);
	for (int m = 0; m < GRAY8_MAX; m++)
		szHistogram[m] *= fNormal;

(3)、计算累积分布函数

//计算累积分布函数、构造灰度映射表
	unsigned char szMapTable[GRAY8_MAX] = {0};
	float fACC = 0.0f;
	for (int m = 0; m < GRAY8_MAX; m++)
	{
		fACC += szHistogram[m];
		szMapTable[m] = fACC * (GRAY8_MAX - 1);
	}

(4)、灰度重映射

//灰度映射
	for (int m = 0; m < nWidth * nHeight; m++)
	{
		unsigned char src = pInputOutputData[m];
		pInputOutputData[m] = szMapTable[src];
	}

3、算法效果与应用

我们使用一副雾霾天气下的的城市图像进行测试,测试效果图如下:

C++数字图像处理(3)—直方图均衡化_第1张图片

图(1)原始图像

C++数字图像处理(3)—直方图均衡化_第2张图片

图(2)、直方图均衡化结果图像

从算法运行的结果来看,不难发现,算法提升了整体的对比度,让图像的清晰度得到了提升。同时,算法也把噪声也进行了放大,比如天空部分。直方图均衡化是常用的图像增强方法,在低照度、有雾等成像的情况下使用较多。在实际中发现,直方图均衡化存在图像白化严重、无法抑制噪声等缺陷,因此,直方图均衡化算法通常与其他细节增强算法一起使用完成算法任务。

你可能感兴趣的:(C++数字图像处理)