一些常用的直方图均衡化算法

直方图均衡化(HE)

直方图均衡化是常用的图像增强的方法。通过一种映射改变图像中的灰度值,增加图像灰度值的动态范围从而增加图像的对比度。过度曝光的图像中的灰度值主要集中在高亮度的范围内,而曝光不足的图像中的灰度值主要集中在低亮度的范围内。使用直方图均衡化技术可以使得整幅图像的灰度值均匀分布在整个动态范围,从而增加图像的对比度,提升视觉观感。

直方图均衡化步骤:
1.统计图像中每个灰度值像素的个数
2.计算每个灰度值像素的频率,并计算累计频率
3.将图像进行映射,图像的灰度值=图像原来灰度值*累计频率

其中使用到累计频率,那么为什么使用累计频率是值得思考的问题?原因如下:
1.像素经过映射之后需要保证原来灰度值大小关系不变,即亮的区域依旧是亮的,暗的区域依旧是暗的,不能将亮的区域变为暗的。映射后图像只是增加对比度,那么使用单调递增的累计分布函数并不会改变这一点。暗处的灰度值较低,与较低的累计分布频率相乘之后依旧较低;亮处的灰度值较高,与较大的累计分布频率相乘之后依旧较高;
2.如果是8位图像,像素值的灰度值范围在0~255之间,与累计分布频率相乘之后灰度值范围不变,不会出现越界的情况。
概率知识:概率密度函数(PDF)、概率分布函数、累积分布函数(CDF)

代码实现:

//直方图均衡化 HE
bool EqualizeHist(Mat gray, Mat result)
{
	//统计0-255像素个数
	map mp;
	for (int i = 0; i < gray.rows; i++)
	{
		uchar* ptr = gray.data + i * gray.cols;   //data Mat指针
		for (int j = 0; j < gray.cols; j++)
		{
			int value = ptr[j];
			mp[value]++;
		}
	}

	//统计0-255像素值的频率,并计算累计频率
	map valuePro;
	int sum = gray.cols * gray.rows;
	double sumPro = 0;
	for (int i = 0; i < 256; i++)
	{
		sumPro += 1.0 * mp[i] / sum;
		valuePro[i] = sumPro;
	}

	//根据累计频率进行转换
	for (int i = 0; i < gray.rows; i++)
	{
		uchar* ptr1 = gray.data + i * gray.cols;
		for (int j = 0; j < gray.cols; j++)
		{
			int value = ptr1[j];
			double p = valuePro[value];
			result.at(i, j) = p * value;
		}
	}

	return true;
}

试了下opencv的equalizeHist()函数,相比之下opencv好像更好一些,但效果真的一般。

直方图均衡化HE缺点

直方图均衡化对于一幅整体偏暗或者偏亮的图像而言比较适用。因为直方图均衡化是对一整幅图像进行映射,并不会对某些区域局部映射,所以对于那些部分区域偏暗或者偏亮的图像而言并不适用。同时直方图均衡化后的图像灰度级会减少,造成图像的一些细节消失

自适应直方图均衡化(AHE)

AHE算法通过对局部区域执行响应的直方图均衡来改变上述问题。该算法首先被开发出来适用于改进航天器驾驶舱的显示效果。其最简单的形式,就是每个像素通过其周边一个矩形范围内的像素的直方图进行均衡化。均衡的方式则完全同普通的均衡化算法:变换函数同像素周边的累积直方图函数(CDF)成比例。

图像边缘的像素需要特殊处理,因为边缘像素的领域不完全在图像内部。这个通过镜像图像边缘的行像素或列像素来解决。直接复制边缘的像素进行扩充是不合适的。因为这会导致带有剑锋的领域直方图。

AHE属性

领域的大小是该方法的一个参数。领域小,对比度得到增强,领域大,则对比度降低。      

当某个区域包含的像素值非常相似,其直方图就会尖状化,此时直方图的变换函数会将一个很窄范围内的像素映射到整个像素范围。这将使得某些平坦区域中的少量噪音经AHE处理后过度放大

限制对比直方图均衡化(CLHE)

限制对比度自适应直方图均衡化(CLAHE)

     CLAHE同普通的自适应直方图均衡不同的地方主要是其对比度限幅。这个特性也可以应用到全局直方图均衡化中,即构成所谓的限制对比度直方图均衡(CLHE),但这在实际中很少使用。在CLAHE中,对于每个小区域都必须使用对比度限幅。CLAHE主要是用来克服AHE的过度放大噪音的问题。 

     这主要是通过限制AHE算法的对比提高程度来达到的。在指定的像素值周边的对比度放大主要是由变换函数的斜度决定的。这个斜度和领域的累积直方图的斜度成比例。CLAHE通过在计算CDF前用预先定义的阈值来裁剪直方图以达到限制放大幅度的目的。这限制了CDF的斜度因此,也限制了变换函数的斜度。直方图被裁剪的值,也就是所谓的裁剪限幅,取决于直方图的分布因此也取决于领域大小的取值。

     通常,直接忽略掉那些超出直方图裁剪限幅的部分是不好的,而应该将这些裁剪掉的部分均匀的分布到直方图的其他部分。如下图所示。

一些常用的直方图均衡化算法_第1张图片

 一些常用的直方图均衡化算法_第2张图片

对图像分块并对每一块进行直方图均衡看似降低了运算量,但可以预见其大概率会导致块效应的出现,故我们需要采用双线性插值来在一定程度上降低块效应。(具体参考文章底部链接文章)

CLAHE算法实现流程

将图像灰度化并调整大小,使其完全分割(调整大小可以采用镜像的方法补齐)

将图像分块,并计算每一块的直方图数组(二维数组)

对每一块的直方图进行对比度限制处理

利用限制后的直方图生成每一块的直方图均衡映射函数(二维数组)

判断像素点的位置并利用相应四个直方图映射函数进行双线性插值得到最终结果

参考文章

直方图均衡化原理及C++实现

限制对比度自适应直方图均衡化算法原理、实现及效果

CLAHE算法

基于直方图的图像增强算法

你可能感兴趣的:(计算机视觉,python,人工智能)