直方图均衡与平台直方图

直方图均衡化(Histogram Equalization)

直方图均衡化处理的“中心思想”是把原始图像的灰度直方图从比较集中的某个灰度区间变成在全部灰度范围内的均匀分布。直方图均衡化就是对图像进行非线性拉伸,重新分配图像像素值,使一定灰度范围内的像素数量大致相同。直方图均衡化就是把给定图像的直方图分布改变成“均匀”分布直方图分布。

直方图均衡化的主要过程

  • 统计每一个灰度值的像素点数和所占的百分比
  • 累加每一个灰度值的百分比
  • 利用新的灰度值的百分比,重新计算每一个灰度值的变化
  • 将新的的对应的关系映射到新的图像中

一个简单的例子

首先需要说明的是,如果你说的是一道完整的题目,则这道题目没有唯一解,因为题目中没有说明原始图像的灰度级数(比如原始图像是16个灰度级的,或者是32个灰度级的,等等)。为了给你提供一个解题思路,现在人为假设原始图像是16个灰度级的,其它灰度级的解法类似。

1、图像的灰度直方图求法为:

(1)先计算图像中各个灰度级的出现频率,用h(i)表示灰度级i的出现频率,其值等于灰度级出现次数/图像像素个数:

h(0)=2/16

h(1)=1/16

h(2)=3/16

h(3)=2/16

h(4)=0/16

h(5)=1/16

h(6)=4/16

h(7)=1/16

h(8)=1/16

h(9)=1/16

h(10)=h(11)=h(12)=h(13)=h(14)=h(15)=0/16。

然后以灰度级i为横轴,出现频率h(i)为纵轴即可绘制出图像对应的直方图。

(2)图像进行直方图均衡化处理的过程为:

先计算累积分布,用r(i)表示灰度级i的累积分布:

r(0)=h(0)=2/16

r(1)=r(0)+h(1)=2/16+1/16=3/16

r(2)=r(1)+h(2)=3/16+3/16=6/16

r(3)=r(2)+h(3)=6/16+2/16=8/16

r(4)=r(3)+h(4)=8/16+0/16=8/16

r(5)=r(4)+h(5)=8/16+1/16=9/16

r(6)=r(5)+h(6)=9/16+4/16=13/16

r(7)=r(6)+h(7)=13/16+1/16=14/16

r(8)=r(7)+h(8)=14/16+1/16=15/16

r(9)=r(8)+h(9)=15/16+1/16=16/16=1

r(10)=r(11)=r(12)=r(13)=r(14)=r(15)=1

将累积分布进行量化(量化时需要用到原始图像的灰度级数,这也是为什么前面需要说明的原因),量化后的灰度级用rq(i)表示,量化公式为rq(i)=ROUND(r(i)*15),(说明:量化公式中的15等于原始图像灰度级数减1),可得:

rq(0)=ROUND(r(0)*15)=2

rq(1)=ROUND(r(1)*15)=3

rq(2)=ROUND(r(2)*15)=6

rq(3)=ROUND(r(3)*15)=8

rq(4)=ROUND(r(4)*15)=8

rq(5)=ROUND(r(5)*15)=8

rq(6)=ROUND(r(6)*15)=12

rq(7)=ROUND(r(7)*15)=13

rq(8)=ROUND(r(8)*15)=14

rq(9)=ROUND(r(9)*15)=15

rq(10)=ROUND(r(10)*15)=15

rq(11)=ROUND(r(11)*15)=15

rq(12)=ROUND(r(12)*15)=15

rq(13)=ROUND(r(13)*15)=15

rq(14)=ROUND(r(14)*15)=15

rq(15)=ROUND(r(15)*15)=15

因此,原始图像中的灰度级和均化后图像中的灰度级之间的对应关系为:

0->2

1->3

2->6

3->8

4->8

5->8

6->12

7->13

8->14

9->15

10->15

11->15

12->15

13->15

14->15

15->15

将原始图像中对应的灰度值安装上述对应关系替换成相应的灰度值,即可得到均化图像,结果如下:

3  8  13  8

6  12  2  12

14  6  12  8

15  6  12  2

关键的代码实现

</pre><pre name="code" class="cpp"><span style="white-space:pre">	</span>Mat src,dest;
<span style="white-space:pre">	</span>Src.copyTo(src);

	if (src.channels() > 1)
	{
		cvtColor(src, src, CV_BGR2GRAY);
	}

	MatND  hist;
	const int histSize = 256;
	float range[] = { 0, 255 };
	const float *ranges[] = { range };
	const int channels = 0;
	cv::calcHist(&src, 1, &channels, Mat(), hist, 1, &histSize, ranges);
	float total = src.size().width* src.size().height;

	float bins[histSize] = { 0 };
	float binsAcc[histSize] = { 0 };
	Mat lut(1, 256, CV_8U);
	vector<float> vectorBins;
	vector<float> maxBins;
	float sumBins = 0.0;
	int countMax = 0;
	float TValue = 0;

	// Find the mapping table
	for (int i = 0; i<histSize; i++)
	{
		float bin_val = hist.at<float>(i); // 第i灰度级上的数
		bins[i] = bin_val / total;

		if (bins[i] > 0)
		{
			vectorBins.push_back(bins[i]);
		}

		if (i>0)
		{
			binsAcc[i] =binsAcc[i-1] + bins[i];
		}
		else
		{
			binsAcc[0] = bins[0];
		}
		lut.at<uchar>(i) = static_cast<uchar>(cvRound(binsAcc[i] * 255));
	}

利用openCV中均衡化的代码只要一句话:

	Mat dest2;
	equalizeHist(src, dest2);
	imshow("equlization2", dest2);

平台直方图及均衡化

平台直方图的概念

这种方法是基于直方图均衡算法的改进算法,它是通过在直方图分布中设计一个阈值T来
对原来直方图进行改造。

这种方法的思路是:如果原直方图中某些灰度级对应的值大于阈值T,就将该处的值设置为T。要是该处的值不大于T时,那么该处的值保持不变。

其中 Pt(k)是平台直方图, Pr(k)是原来的直方图

和直方图均衡类似,对平台直方图进行累加计算,得到累积函数

然后通过均衡化把原图灰度值改为新的灰度值

在这种方法中T的确定是最主要的任务,它的确定方法介绍如下

平台阈值的确定

关键代码实现

        Mat src,dest;
	Src.copyTo(src);

	if (src.channels() > 1)
	{
		cvtColor(src, src, CV_BGR2GRAY);
	}

	MatND  hist;
	const int histSize = 256;
	float range[] = { 0, 255 };
	const float *ranges[] = { range };
	const int channels = 0;
	cv::calcHist(&src, 1, &channels, Mat(), hist, 1, &histSize, ranges);
	float total = src.size().width* src.size().height;

	float bins[histSize] = { 0 };
	float binsAcc[histSize] = { 0 };
	Mat lut(1, 256, CV_8U);
	vector<float> vectorBins;
	vector<float> maxBins;
	float sumBins = 0.0;
	int countMax = 0;
	float TValue = 0;

	// Find the mapping table
	for (int i = 0; i<histSize; i++)
	{
		float bin_val = hist.at<float>(i); // 第i灰度级上的数
		bins[i] = bin_val / total;

		if (bins[i] > 0)
		{
			vectorBins.push_back(bins[i]);
		}

	}

	// Calculate the Meadin value by 3 sapce
	for (int i = 1; i < vectorBins.size() - 1; i++)
	{
		if (vectorBins[i] < vectorBins[i - 1] && vectorBins[i - 1] < vectorBins[i + 1] || vectorBins[i] > vectorBins[i - 1] && vectorBins[i - 1]  > vectorBins[i + 1])
		{
			vectorBins[i] = vectorBins[i - 1];
		}
		else if (vectorBins[i] < vectorBins[i + 1] && vectorBins[i + 1] < vectorBins[i - 1] || vectorBins[i] > vectorBins[i + 1] && vectorBins[i + 1] > vectorBins[i - 1])
		{
			vectorBins[i] = vectorBins[i + 1];
		}
	}

	// Calculate the max peak value
	for (int i = 1; i < vectorBins.size() - 1; i++)
	{
		if (vectorBins[i] - vectorBins[i - 1] >= 0 && vectorBins[i+1] - vectorBins[i] <= 0)
		{
			maxBins.push_back(vectorBins[i]);
			sumBins += vectorBins[i];
			countMax++;
		}
	}

	TValue = sumBins / countMax;

	// Find the mapping table
	for (int i = 0; i<histSize; i++)
	{

		if (bins[i] > TValue)
		{
			bins[i] = TValue;
		}

		if (i>0)
		{
			binsAcc[i] = binsAcc[i - 1] + bins[i];
		}
		else
		{
			binsAcc[0] = bins[0];
		}
	}

	for (int i = 0; i < histSize; i++)
	{
		lut.at<uchar>(i) = static_cast<uchar>(cvRound(binsAcc[i] * 255 / binsAcc[255]));
	}

	LUT(src, lut, dest);
	imshow("src", src);
	imshow("equlization", dest);

欢迎转载,请注明本文的出处:http://blog.csdn.net/fioletfly/article/details/51011399  谢谢!

时间: 2024-10-07 21:09:16

直方图均衡与平台直方图的相关文章

OpenCV成长之路:图像直方图

http://ronny.blog.51cto.com/8801997/1394115 2014-04-11 13:47:27 标签:opencv 直方图 统计表 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://ronny.blog.51cto.com/8801997/1394115 一.图像直方图的概念 图像直方图是反映一个图像像素分布的统计表,其实横坐标代表了图像像素的种类,可以是灰度的,也可以是彩色的.纵坐标代表了每一种

OpenCV入门教程之四 图像直方图

一.图像直方图的概念 图像直方图是反映一个图像像素分布的统计表,其实横坐标代表了图像像素的种类,可以是灰度的,也可以是彩色的.纵坐标代表了每一种颜色值在图像中的像素总数或者占所有像素个数的百分比. 图像是由像素构成,因为反映像素分布的直方图往往可以作为图像一个很重要的特征.在实际工程中,图像直方图在特征提取.图像匹配等方面都有很好的应用.  二.利用OpenCV计算图像的直方图 OpenCV中计算图像直方图像函数是calcHist,它的参数比较多,下面分析一下它的接口和用法. void calc

[openCV]直方图均衡

1.图像的直方图 图像的直方图,代表了图像的灰度值的分布状况.从直方图上,我们可以很明确的知道,图像的偏暗程度和饱和程度.如果一幅数字图像中,假设作为水平轴的灰度值rk出现了nk次,那么对应于垂直轴的归一化后的函数如下所示. pk=nkMN 这样的图像,被称为直方图.为了直观感受一下直方图的作用,我使用相机调节曝光补偿,拍摄了以下3枚图像. 从图像的上方的直方图就可以看出来,图像的偏暗程度与饱和程度.并且,可以将左图像与中央图像称为动态范围较窄的图像.相反的,对于右边图像,其动态范围较宽,图像得

【图像处理】第一次实验

1.任务说明 打开一幅图像,进行直方图均衡.将灰度线性变化,将灰度拉伸. 2.算法原理 1)        图像灰度化 在RGB模型中,如果R=G=B时,则彩色表示一种灰度颜色,其中R=G=B的值叫做灰度值,灰度范围为0-255.一般有四种方法对彩色进行灰度化,分别为: 分量法,最大值法,平均值法和加权平均法.本实验中采用平均值法,即 2)        直方图均衡 直方图表示数字图像中每一个灰度级与其出现频率间的统计关系.设有某一个灰度等级,属于该灰度等级的像素个数为nk,图像总像素个数为n,

OpenCV2学习笔记(二):图像的直方图

直方图(Histogram)又称质量分布图.是一种统计报告图,由一系列高度不等的纵向条纹或线段表示数据分布的情况.一般用横轴表示数据类型,纵轴表示分布情况.众所周知,一幅图像是由不同颜色值的像素组成,因此像素值在图像中的分布情况是这幅图像的一个重要特征,因此直方图广泛应用在数字图像处理中. 拍照是现实生活中必不可少的一部分,由于环境亮度.图像拍摄过程中透视光圈设置错误等影响,经常会拍出一些"过暗"的照片,此时美图.PS等美化工具可以派上用场.但是这些工具的算法通常都是不公开的,鉴于研究

直方图均衡

直方图均衡化的目的是为了找到并应用一个点运算使得修正后图像的直方图近似于一个均匀分布.基本思想是对于一幅图像(原始直方图为h)找到并应用一种点运算,使得修正后的图像的直方图heq近似均匀分布,因此累计直方图Heq应该近似楔形.由于直方图是一个离散分布,均匀点运算只能移动和合并直方图条目,所以只能在整体上得到一个近似的解. 根据以上变换思想,所求的点运算可以从原始图像的累积直方图H中求得: 其中图像大小为M×N,像素取值范围为[0,K-1].用Matlab实现的代码如下所示: %% I = imr

Matlab图像处理系列1———线性变换和直方图均衡

注:本系列来自于图像处理课程实验,用Matlab实现最基本的图像处理算法 图像点处理是图像处理系列的基础,主要用于让我们熟悉Matlab图像处理的编程环境.灰度线性变换和灰度拉伸是对像素灰度值的变换操作,直方图是对像素灰度值的统计,直方图均衡是对灰度值分布的变换. 1.灰度线性变换 (1)线性变换函数 原图向灰度值为g,通过线性函数f(x)=kx+b转换为f(g)得到灰度的线性变换. (2)代码实现 Matlab中支持矩阵作为函数参数传入,定义一个线性转换函数,利用Matlab矩阵操作,用一行代

opencv直方图均衡化

#include <iostream> #include "highgui.h" #include "cv.h" #include "cxcore.h" #include "math.h" using namespace std; using namespace cv; //绘制1维直方图 Mat draw1DHistogram(Mat histogramMat) { double maxVal = 0, minV

基于直方图的图像增强算法(HE、CLAHE、Retinex)之(一)

直方图是图像色彩统计特征的抽象表述.基于直方图可以实现很多有趣的算法.例如,图像增强中利用直方图来调整图像的对比度.有人利用直方图来进行大规模无损数据隐藏.还有人利用梯度直方图HOG来构建图像特征进而实现目标检测.本节我们就来讨论重要的直方图均衡化算法,说它重要是因为以此为基础后续又衍生出了许多实用而有趣的算法. Histogram equalization 如果一幅图像的像素灰度值在一个过于有限的范围内聚集,那么图像的程序效果即会很糟糕,直接观感就是对比度很弱.下图来自维基百科,第一幅图的直方