直方图均衡化的计算

Python010

直方图均衡化的计算,第1张

《计算机视觉教程》笔记

编著:章毓晋(清华大学电子工程系)

出版社:人民邮电出版社

出版时间:2017.3

例3.3.1 直方图均衡化列表计算示例

  设有一幅64×64,8 bit的灰度图像,其直方图如图3.3.2(a)所示。所用的均衡化变换函数(即累积直方图)如图3.3.2(b)所示,均衡化后得到的直方图如图3.3.2(c)所示。需注意,由于不能(或者说没有理由)将同一个灰度值的各个像素变换到不同灰度级,所以数字图像直方图均衡化的结果一般只是近似均衡的直方图。这里可试比较图 3.3.2(d)所示的粗折线(实际均衡化结果)与水平直线(理想均衡化结果),图中虚线为原直方图包络。

  实际中进行直方图均衡化计算可采用列表的方式。表3.3.1所示为以上直方图均衡化的运算步骤和结果(其中第4步的取整表示取方括号中实数的整数部分)。

由表3.3.1可见,原始直方图的一些不同灰度有可能映射到均衡化直方图的同一个灰度,所以均衡化直方图中实际使用的灰度级数有可能比原始直方图的灰度级数少。

  图3.3.3所示为直方图均衡化的一个实例。图3.3.3(a)和(b)分别为一幅8 比特灰度级的原始图像和它的直方图。这里原始图像较暗且动态范围较小,反映在直方图上就是其直方条所占据的灰度值范围比较窄,且集中在低灰度值一边。图3.3.3(c)和(d)分别为对原始图进行直方图均衡化得到的结果及其对应的直方图,现在直方图占据了整个图像灰度值所允许的范围。由于直方图均衡化增加了图像灰度动态范围,所以也增加了图像的对比度,反映在图像上就是图像有较大的反差,许多细节可看得比较清晰了。但需要注意,直方图均衡化在增强反差的同时也增加了图像的可视粒度,即图像中有许多粗颗粒的像素团点/团块出现。

设原始图像在(x,y)处的灰度为f,而改变后的图像为g,则对图像增强的方法可表述为将在(x,y)处的灰度f映射为g。

在灰度直方图均衡化处理中对图像的映射函数可定义为:g = EQ (f)。

这个映射函数EQ(f)必须满足两个条件(其中L为图像的灰度级数):

(1)EQ(f)在0≤f≤L-1范围内是一个单值单增函数。这是为了保证增强处理没有打乱原始图像的灰度排列次序,原图各灰度级在变换后仍保持从黑到白(或从白到黑)的排列。 

(2)对于0≤f≤L-1有0≤g≤L-1,这个条件保证了变换前后灰度值动态范围的一致性。

扩展资料:

直方图均衡化作用

这种方法通常用来增加许多图像的全局对比度,尤其是当图像的有用数据的对比度相当接近的时候。通过这种方法,亮度可以更好地在直方图上分布。

这样就可以用于增强局部的对比度而不影响整体的对比度,直方图均衡化通过有效地扩展常用的亮度来实现这种功能。

这种方法对于背景和前景都太亮或者太暗的图像非常有用,这种方法尤其是可以带来X光图像中更好的骨骼结构显示以及曝光过度或者曝光不足照片中更好的细节。

这种方法的一个主要优势是它是一个相当直观的技术并且是可逆操作,如果已知均衡化函数,那么就可以恢复原始的直方图,并且计算量也不大。这种方法的一个缺点是它对处理的数据不加选择,它可能会增加背景噪声的对比度并且降低有用信号的对比度。

在统计学中,直方图(英语:Histogram)是一种对数据分布情况的图形表示,是一种二维统计图表,它的两个坐标分别是统计样本和该样本对应的某个属性的度量。直方图是品质管理七大工具之一。

把直方图上每个属性的计数除以所有属性的计数之和,就得到了归一化直方图。之所以叫“归一”,是因为归一化直方图的所有属性的计数之和为1,也就是说,每个属性对应计数都是0到1之间的一个数(百分比)。

参考资料来源:百度百科-直方图均衡化

#include <math.h>

#include <conio.h>

#include <stdio.h>

#include <stdlib.h>

#include <graphics.h>

int main()

{

int GraphDriver

int GraphMode

int i, x, y

char buffer[5]

int data[]={7,3,12,6,9,5,8,11}

GraphDriver = DETECT /*自动检测图形设备*/

initgraph(&GraphDriver, &GraphMode, "")/*初始化图形设备*/

setcolor(15) /*设置前景色,白色*/

moveto(635, 461) /*移动画笔至点(635,461)*/

lineto(20, 461) /*从当前画线至(20,461),并移画笔到(20,461),画x轴*/

lineto(20, 20) /*从当前画线至(20,20),并移画笔到(20,20),画y轴*/

setcolor(15) /*设置前景色,白色*/

for (i = 1 i <13i++)

{

itoa(i, buffer, 10) /*将i以十进制形式转换成字符串,保存在buffer*/

outtextxy(20 - textwidth(buffer), 456 - i * 36, buffer)/*在适当位置输出y轴的刻度对应的标签*/

moveto(20, 460 - i * 36)/*画笔移至y轴刻度起点*/

lineto(23, 460 - i * 36)/*画y轴刻度*/

}

setfillstyle(SOLID_FILL, 1)/*设置填充模式(配合直方图)*/

for (i = 0 i <8i++)

{

moveto(i * 50 + 49, 461)/*移动画笔至x刻度处*/

lineto(i * 50 + 49, 465)/*画x刻度*/

outtextxy(i * 50 + 51, 463, itoa(i + 1, buffer, 10)) /*输出x轴刻度*/

bar(i * 50 + 35, 460 - data[i] * 36, i * 50 + 65, 460)/*画直方图*/

}

getch() /*等待一个按键*/

closegraph() /*关闭图形模式*/

}