图像处理:直方图规定化

    直方图均衡化能够自动的扩展图像灰度的动态范围从而提高图像的对比度增强视觉效果。但是并非所有的图像都适合直方图均衡化,例如图像中大部分灰度值接近0时,由于接近0的像素多权重大,根据均衡原理使用(L-1)*累计概率会造成暗像素的值急剧上升,最终图像亮度变高出现“冲淡效果”。而直方图规定化是使图像具有指定的概率密度分布,在一些情况下能够获得更好的处理效果。

简单叙述一下具体的步骤:

(1)计算图像直方图并进行直方图均衡化得到变化后的灰度。

(2)利用规定的直方图进行直方图均衡化获得变换函数G的所有值,将G的值存入表中。

(3)对于每个均衡化灰度S,在G值得表中找相应的Z值,使得G的值最接近S值,并存储S到Z的映射。

(4)建立原始图想灰度R到Z的映射,最后根据映射关系重建图像,即可获得均衡化图像。

    代码本来想在网上撸一个,结果感觉都看不懂,还是根据原理自己使用C++写一个吧,关键是使用数据结构Map建立映射表。主要代码封装成下面函数HistogramSpecification(Mat &src, Mat &dst, float zhist[])。

/************************************************
@参数:Mat &src  输入图像
@参数:Mat &dst  输出图像
@参数:float zhist[] 规定化的归一化直方图
************************************************/
void HistogramSpecification(Mat &src, Mat &dst, float zhist[])
{
	src.copyTo(dst);     //src拷贝到dst

	int h = src.rows;    //图像高度
	int w = src.cols;    //图像宽度

	int hist[256] = {0};  //各级像素数目
	int S[256] = { 0 };
	map<int, int> S2Z;    //S到Z的映射
	map<int, int> r2z;    //r到Z的映射

	//直方图统计
	for (int i = 0; i < h; i++) {
		uchar* p = src.ptr<uchar>(i);
		for (int j = 0; j < w; j++){
			int vaule = p[j];
			hist[vaule]++;
		}
	}

	//归一化累加直方图
	float sumhist[256] = { 0 };
	for (int i = 0; i < 256; i++){
		int sum = 0;
		for (int j = 0; j <= i; j++)
			sum += hist[j];
		sumhist[i] = sum*1.0 / (h*w);
	}

	//根据sumhist建立均衡化后灰度级数组S
	for (int i = 0; i < 256; i++)
		S[i] = 255 * sumhist[i] + 0.5;
	
	//根据zsumhist建立均衡化后灰度级数组G
	int G[256] = { 0 };
	float zsumhist[256] = { 0.0 };

	for (int i = 0; i < 256; i++){
		float sum = 0;
		for (int j = 0; j <= i; j++)
			sum += zhist[j];
		zsumhist[i] = sum;
	}

	for (int i = 0; i < 256; i++)
		G[i] = zsumhist[i] * 255 + 0.5;

	//令G(Z)=S 建立S->Z的映射表
	for (int i = 0; i < 256; i++) {
		for (int j = 1; j < 256; j++){
			if (abs(S[i] - G[j - 1]) < abs(S[i] - G[j]))
			{
				S2Z[S[i]] = j - 1; 
				break;
			}
		}
	}
	S2Z[S[255]] = G[255];

	//建立r->z映射,即为原像素到规定化像素的映射
	for (int i = 0; i < 256; i++)
		r2z[i] = S2Z[S[i]];

	//重建图像
	for (int i = 0; i < h; i++) {
		uchar *pdata = dst.ptr<uchar>(i);
		for (int j = 0; j < w; j++){
			*(pdata + j) = r2z[*(pdata + j)];
		}
	}
}


由于规定化的直方图是根据实际需求而设计的,所以没有统一标准。在这里我的直方图如下:

对比一下均衡化的效果和规定化的效果:

    上图下对比还是比较明显的,均衡化的效果真的不好,规定化的效果稍微强一点(主要是我使用的规定化直方图是瞎整的)。若想要获得更好的效果可以更具实际情况改变规定化直方图。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值