基于Python的直方图均衡探讨

作者: 惠为君

基于Python的直方图均衡探讨0

摘要:直方图均衡是一种图像增强的基本算法。其原理是利用概率论的分布知识,对源图像的像素值进行变换,使得目标图像的直方图在灰度范围内均匀分布。由于图像的像素分布变宽,图像对比度加强,因而目标图像更清晰。基于Python和OpenCV工具实现JPEG图像直方图均衡算法。测试表明,算法的实现是成功的。

关键词:Python;图像增强;直方图均衡;均匀分布

中图分类号:TN91      文献标识码:A

文章编号:1009-3044(2023)25-0095-03

开放科学(资源服务)标识码(OSID)

0 引言

图像增强是指对图像进行灰度变换,使图像与视觉响应相匹配,加强图像的视觉效果的一种图像处理方法。灰度变换的方法很多,其中的一种是点运算,指用一个单调递增的函数对原图像的灰度进行非线性运算,从而实现对比度增强[1-3]。

如图1所示,x表示变换源图像的灰度值,y表示目标图像的灰度值。变换函数y=T(x)需要满足以下两个要求:

1) [0≤x≤255, 0≤y≤255], x和y的取值范围相同。这一条保证变换以后,像素值不能超过范围。

2) T(x)在区间[0 255]上严格单调递增。这一条保证源像素值和目标像素值大小一一对应。不允许出现灰度倒置甚至于灰度翻转,否则影响视觉效果。

不是所有的单调递增函数都可用于灰度变换。常用的变换函数有两种形式,函数Ⅰ和函数Ⅱ。对于函数Ⅰ, 源图像像素范围[0 128]变换到[0  N2],对于函数Ⅱ,则变换到[0  N1]。可以看出,N2>128,N1<128, 函数Ⅰ拉伸了低灰度级,压缩了高灰度级,函数Ⅱ则相反。可知,曲线斜率大于1的时候,灰度拉伸,小于1的时候,灰度压缩。

1 直方图均衡原理

一幅数字图像中,不同灰度值的像素的数目是不同的。由于光照等的影响,像素值的分布不同,如果光照较强,高灰度级像素较多,如果光照弱,低灰度级像素较多[4]。

设置的变换函数需要把灰度值相对集中的灰度范围拉伸,灰度值分布较少的灰度范围压缩,使得总体上灰度的分布更均匀。

在需要拉伸的灰度区域,设置的变换函数斜率大于1,在需要压缩的灰度区域变换函数斜率小于1。因此,灰度值越集中,对应的变换函数的斜率越大,反之越小,灰度变换函数的斜率与灰度分布有关。

直方图均衡指的是利用图像的直方图,构建符合以上要求的变换函数,实现图像增强[5]。

为了方便讨论,假设图像的灰度值连续分布,其取值范围[0,L-1]。灰度值分布具有随机性,用概率密度为[f(x)]表示,其含义表示灰度值x附近单位区间的像素数目占总数的百分比。

分布函数[F(x) =0xf(r)dr] 是一个单调递增函数,其取值范围[0  1]。定义函数y = T(x),如公式(1) 所示。

[y=T(x)=(L-1)F(x)]  (1)

T(x)单调递增,x,y的灰度值变化范围都取[0,L-1],符合变换函数的要求。灰度值y对应的概率密度为g(y)。对于任意x, 必然存在y,使得公式(2) 成立。

[0yg(s)ds=0xf(r)dr]    (2)

式(2) 两边对x求导:[g(y)dy/dx=f(x)]

式(1) 对x求导: [dy/dx=(L-1)f(x)]

得到[g(y)=1/(L-1)]

变换以后,概率密度函数g(y)为常数,灰度值分布为均匀分布。变换之前,x的分布局限在一个较小的范围,反映在视觉效果上,图像不清晰,变换以后灰度值分布是均匀的,图像对比度增强,在视觉效果上图像更清晰。

对于数字图像,j表示灰度级,[xj]表示灰度级j对应的灰度值,[nxj]表示灰度值为[xj]的像素数目。灰度值[xj]的范围为[0,L-1],N表示像素的总数目。和模拟图像对应的数字图像变换函数定义如表1所示。最终得到变换函数:

[yi=T(xi)=(L-1)j=0i-1nxjN]    (3)

由于变换函数与直方图有关,变换结果为均匀分布,因此称这种图像增强方法为直方图均衡。[yi]为目标图像的灰度值,[xi]为源图像的灰度值,i为对应的灰度级。

2 Python实现

直方图均衡算法实现步骤如下:

1) 获取图像灰度级分布i。

2) 统计灰度级i对应的像素数目ni。

3) 计算灰度直方图的归一化概率表达式:p(si)=ni/N, N为像素总的数目。

4) 计算累积灰度直方图。

5) 进行取整扩展,计算映射后输出图像各灰度级对应灰度值的归一化表达形式tk。

6) 确定映射关系sk→tk。

7) 统计映射后各灰度级的像素数目nk。

8) 得到新的灰度统计直方图的归一化概率表达形式:pt(tk)=nk/N,N为输出图像的像素数目,即原始图像的像素数目。

基于Python和OpenCV实现以上直方图均衡算法[6-7]。其步骤如下:

1) 调用cv2.imread()函数,读取JPEG数字图像[2],通过参数设置,直接保存为 n灰度图像数据。对各个灰度级进行累计计算,并归一化。

2) 累积直方图函数pix_gray (img_gray),累积直方图函数乘以(L-1)得到转换函数。

3) 利用转换函数实现源图像的直方图均衡,得到目标图像。

4) 保存目标图像。

在读取图像之后,实现直方图灰度级统计的函数如下:

def pix_gray (img_gray):

h = img_gray.shape[0]

w = img_gray.shape[1]

gray_level = np.zeros(256)

gray_level2 = np.zeros(256)

for i in range (1,h-1):

for j in range(1,w-1):

gray_level[img_gray[i,j]] += 1  #统计灰度级为img_gray[i,j]的个数

for i in range(1,256):

gray_level2[i] = gray_level2[i-1] + gray_level[i]  #统计灰度级小于img_gray[i,j]的个数

return gray_level2

其中,gray_level存放各灰度级的像素的数目,gray_level2存放累积灰度的值,也就是变换函数的值。

实现直方图均衡关键算法的Python函数如下:

def hist_gray(img_gary):

h,w = img_gary.shape

gray_level2 = pix_gray(img_gray)

lut = np.zeros(256)

for i in range(256):

lut[i] = 255.0/(h*w)*gray_level2[i] #得到新的灰度级

lut = np.uint8(lut + 0.5)

out = cv2.LUT(img_gray,lut)

return out。

其中,N = h×w,表示总的像素数目,lut存放变换的结果。

3 测试及分析

测试了三种256色灰度图像,这三种图像的灰度值分布都比较集中,一种灰度值较小的像素较多,如图2所示,一种灰度值居中的像素较多,如图3所示,一种灰度值较大的像素较多,如图4所示。

由图2直方图可知,图像像素值主要分布在0~100之间,源图像偏暗。转换函数分为两个部分,0~100之间部分斜率较大,对0~100级之间的灰度有很好的拉伸效果。由于拉伸以后,图像灰度均匀分布,目标图像清晰很多。

由图3直方图可知,图像像素值主要分布在100~200之间,源图像灰蒙蒙的。转换函数在100~200之间部分斜率较大,对100~200级之间的灰度有很好的拉伸效果。由于拉伸以后,汽车和地砖清晰很多。

由图4直方图可知,图像像素值主要分布在100~255之间,源图像偏亮。转换函数在100~200之间部分斜率较大,对100~255级之间的灰度有很好的拉伸效果。由于拉伸以后,阳光下的植物清晰很多。

4 结束语

由于光照等环境的影响,图像的灰度值分布可能比较集中,这就导致图像对比度较小、不清晰。利用直方图累积函数作为变换函数可以对源图像进行点运算,对源图像的灰度范围进行拉伸或压缩,目标图像的灰度值将是均匀分布,这样图像的对比度将增强,清晰度将提高。直方图均衡将灰度值集中的灰度值拉伸,并不代表灰度值一定增多。

参考文献:

[1] 武英.基于双直方图均衡的自适应图像增强算法[J].计算机工程,2011,37(4):244-245.

[2] 韩晓冬,王浩森,王硕,等.Python在图像处理中的应用[J].北京测绘,2018,32(3):312-317.

[3] 张璋.计算机技术在图像处理中的应用分析[J].才智,2018(16):237.

[4] 罗伙根.一种改进的直方图均衡实时图像增强算法[J].硅谷,2010(8):4-42.

[5] 杨卫中,徐银丽,乔曦,等.基于对比度受限直方图均衡化的水下海参图像增强方法[J].农业工程学报,2016,32(6):197-203.

[6] 方玫.OpenCV技术在数字图像处理中的应用[J].北京教育学院学报(自然科学版),2011,6(1):7-11.

[7] 刘培军,马明栋,王得玉.基于OpenCV图像处理系统的开发与实现[J].计算机技术与发展,2019,29(3):127-131.

【通联编辑:谢媛媛】

上一篇 点击页面呼出菜单 下一篇