直方图均衡化原理与实现


直方图均衡化是一种增强图像对比度常用的一种方式,主要思想是将图像的直方图分布映射为近似均匀分布,从而增强图像的对比度。原始图像由于其灰度分布可能集中在较窄的区间,造成图像不够清晰。例如,过曝光图像的灰度级集中在高亮度范围内,而曝光不足将使图像灰度级集中在低亮度范围内。采用直方图均衡化,可以把原始图像的直方图变换为均匀分布(均衡)的形式,这样就增加了像素之间灰度值差别的动态范围,从而达到增强图像整体对比度的效果。

直方图均衡化原理

原理介绍

对于一幅图像,我们用 r r r 表示待处理的图像图像灰度级,假设 r r r 的取值区间是 [ 0 , L − 1 ] [0, L-1] [0,L1], r r r 代表图像的256个灰度级。 r r r满足如下关系式:
s = T ( r ) , 0 < r < L − 1 s= T(r), 0<r<L-1 s=T(r),0<r<L1
其满足以下条件:
(a) T ( r ) T(r) T(r)在区间 0 < r < L − 1 0<r<L-1 0<r<L1 为单调递增函数
(b) 当 0 < L − 1 0<L-1 0<L1 时, 0 < T ( r ) < L − 1 0<T(r)<L-1 0<T(r)<L1
条件(a)中要求 T ( r ) T(r) T(r)为单调递增函数是为了保证输出灰度值不少于相应的输入灰度值,防止灰度反变换时产生人为缺陷。条件(b)保证输入灰度的范围和输出灰度的范围相同。
直方图均衡化的目的就是求 T ( r ) T(r) T(r)的函数表达式。
对于连续的情况:
s = T ( r ) = ∫ 0 r p r ( r )   d r s=T(r)=\int_0^r {p_r(r)} \,{\rm d}r s=T(r)=0rpr(r)dr
对于离散的情况:
s k = T ( r k ) = ∑ i = 0 k p r ( r i ) = ∑ i = 0 k n i N s_k=T(r_k)=\sum_{i=0}^kp_r(r_i)=\sum_{i=0}^k\frac{n_i}{N} sk=T(rk)=i=0kpr(ri)=i=0kNni

计算步骤

① 统计每个灰度级像素个数
② 计算累积概率密度函数
③ 根据累积概率密度求灰度映射表
④ 根据映射表计算映射后的灰度值

代码实现

代码实现如下:

// src:src image data
// dst:dst image data
// height: image height
// width: image width
void equalizeHist(unsigned char* src, unsigned char*dst, int &height, int &width)
{
	const int hist_sz = 256;
	int hist[hist_sz] = { 0, };
	int lut[hist_sz];
	for (int i = 0; i < height; i++)
	{
		for (int j = 0; j < width; j++)
			hist[src[i*width + j]]++;
	}

	int i = 0;
	while (!hist[i])
		i++;

	int total = width * height;
	if (hist[i] == total)
	{
		//原始图像只有一个灰度级
		std::for_each(dst, dst + total, [i](unsigned char& value) { value = i; });
		return;
	}
	float scale = (hist_sz - 1.f) / (total - hist[i]);
	int sum = 0;
	//将第一个灰度级置为0
	for (lut[i++] = 0; i < hist_sz; i++)
	{
		sum += hist[i];
		lut[i] = static_cast<unsigned char>(sum * scale + 0.5f);
	}
	for (int y = 0; y < height; ++y) {
		for (int x = 0; x < width; ++x) {
			dst[y * width + x] = static_cast<unsigned char>(lut[src[y * width + x]]);
		}
	}
}

处理结果:

处理的结果和opencv函数接口cv::equalizeHist的结果一致。

参考文献:

  1. Rafael C. Gonzalez, Richard E. Woods,Digital Image Processing (Third Edition)
  2. 直方图均衡化博客

感兴趣的同学可以了解下Cuda实现直方图均衡化 ,有具体的代码实现。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值