灰度图的直方图均衡化的原理及实现

直方图均衡化的作用是图像增强。
有两个问题比较难懂,一是为什么要选用累积分布函数,二是为什么使用累积分布函数处理后像素值会均匀分布。
第一个问题。均衡化过程中,必须要保证两个条件:①像素无论怎么映射,一定要保证原来的大小关系不变,较亮的区域,依旧是较亮的,较暗依旧暗,只是对比度增大,绝对不能明暗颠倒;
②如果是八位图像,那么像素映射函数的值域应在0和255之间的,不能越界。综合以上两个条件,累积分布函数是个好的选择,因为累积分布函数是单调增函数(控制大小关系),并且值域是0到1(控制越界问题),所以直方图均衡化中使用的是累积分布函数。
第二个问题。累积分布函数具有一些好的性质,那么如何运用累积分布函数使得直方图均衡化?

比较概率分布函数和累积分布函数,前者的二维图像是参差不齐的,后者是单调递增的。直方图均衡化过程中,映射方法是:


其中,n是图像中像素的总和,nk是当前灰度级的像素个数,L是图像中可能的灰度级总数。
来看看通过上述公式怎样实现的拉伸。假设有如下图像:



得图像的统计信息如下图所示,并根据统计信息完成灰度值映射:



映射后的图像如下所示:



灰度直方图均衡化实现的步骤:

1.统计灰度级中每个像素在整幅图像中的个数

2.计算每个灰度级占图像中的概率分布

3.计算累计分布概率

4.计算均衡化之后的灰度值

5.映射回原来像素的坐标的像素值


放上源代码:

#include<opencv2\opencv.hpp>
#include<cmath>
#include<iostream>
using namespace cv;
using namespace std;
Mat MyequalizeHist(Mat &srcImage)  
{
	int nRows = srcImage.rows;
	int nCols = srcImage.cols;

	int nSumPix[256];
	double nProDis[256];
	double nSumProDis[256];
	int EqualizeSumPix[256];

	for (int i = 0; i < 256; i++)
	{
		nSumPix[i] = 0;
		nProDis[i] = 0.0;
		nSumProDis[i] = 0.0;
		EqualizeSumPix[i] = 0;
	}

	for (int i = 0; i < nRows; i++)
	{
		for (int j = 0; j < nCols; j++)
		{
			nSumPix[(int)srcImage.at<uchar>(i, j)]++;
		}
	}
	
	
	for (int i = 0; i < 256; i++)
	{
		nProDis[i] = (double)nSumPix[i] / (nRows * nCols);
	}
	
	
	nSumProDis[0] = nProDis[0];

	
	for (int i = 1; i < 256; i++)
	{
		nSumProDis[i] = nSumProDis[i - 1] + nProDis[i];
	}
	
	
	for (int i = 0; i < 256; i++)
	{
		EqualizeSumPix[i] = cvRound((double)nSumProDis[i] * 255);
	}
	
	Mat resultImage(nRows, nCols, srcImage.type());
	for (int i = 0; i < nRows; i++)
	{
		
		for (int j = 0; j < nCols; j++)
		{
			
			resultImage.at<uchar>(i, j) = EqualizeSumPix[(int)srcImage.at<uchar>(i, j)];
		}
	}
	return resultImage;

}
int main()
{
	Mat srcIamge = imread("flower.jpg");
	if (!srcIamge.data)
	{
		printf("image could not load...\n");
		return -1;
	}
	Mat srcGray;
	//转化为灰度图并且显示
	cvtColor(srcIamge, srcGray, CV_BGR2GRAY);
	imshow("srcGray", srcGray);
	
	Mat resultImage = MyequalizeHist(srcGray);
	imshow("res", resultImage);

	waitKey(0);
	return 0;
}


原图:



效果图:



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值