Copyright © 2021 @Linyer. All Rights Reserved.

参考资料:

  • @刘永雄要好好写博客 的文章 直方图均衡化与Matlab代码实现
  • @云时之间 的文章 数字图像处理:直方图均衡化
  • @不用先生 的文章 【图像处理】直方图均衡化(附带Matlab及OpenCV3自编程实现代码)
  • @只(挚)爱图像处理 的文章 限制对比度自适应直方图均衡化算法原理、实现及效果
  • @xiaoluo91 的文章 对比度受限的自适应直方图均衡化(CLAHE)

文章目录

  • 经典 直方图均衡化(HE)
    • 概述
    • 步骤
    • 公式推导
    • Matlab 代码实现
  • 自适应直方图均衡化(AHE)
    • 限制对比度直方图均衡(CLAHE)

经典 直方图均衡化(HE)

概述

  • 直方图均衡化(Histogram Equalization)又称直方图平坦化,实质上是对图像进行非线性拉伸,重新分配图像象元值,使一定灰度范围内象元值的数量大致相等。这样,原来直方图中间的峰顶部分对比度得到增强,而两侧的谷底部分对比度降低,输出图像的直方图是一个较平的分段直方图,如果输出数据分段值较小的话,会产生粗略分类的视觉效果。

  • 根据香农定理关于信息熵的定义:

    H(X)=−∑p(xi)log⁡(p(xi))(i=1,2,⁣⋯,n)H(X)=-\sum p(x_i)\log(p(x_i))\quad (i=1,2,\dotsi,n)H(X)=−∑p(xi​)log(p(xi​))(i=1,2,⋯,n)

  • 对于一副图像而言,当每一个灰度值分布更均衡,图像所包含的信息量是越大的;相反,仅仅只有一个灰度值的时候,信息量很少。这个是我们能够想来的比如:纯黑图像包含信息量很少,而其他图像我们可能会看到一些人物、景物。

  • 就效果而言,直方图均衡化使得图像信息量变大,但是不可能会发生较小的灰度值在经过均衡化后变得比原来较大的灰度值更大。这也就意味着,我们通过均衡化后的图所观察到的景物应当与原来图像所观察到的一致,只是颜色层次更清晰,更加具有辨识度。

  • 缺点

    • 增强后图像的灰度级会变少,部分细节会消失。(概率相似的几个灰度级均衡化后可能会归为同一灰度级)
    • 当输入图像的直方图有非常密集的部分时,增强后的图像的对比度会增强过度。

步骤

假设有一幅图像,共有64×64个像素,8个灰度级,各灰度级概率分布见下表 ,试将其直方图均匀化。

  1. 确定图像的灰度级
    在实际情况下,如果我们的图像是彩色,需要将其转换为灰度图像,其中的灰度级一般是0-255,这里的灰度级只取8级。

  2. 计算原始直方图的概率
    统计每一个灰度在原始图像上的像素所占总体的比例,记为Pi

  3. 计算直方图概率的累加值S(i)
    直到最后一个灰度级,总和为 1

    由公式:
    Sk=T(rk)=∑j−0kPr(rj)=∑j−0knjNS_k=T(r_k)=\displaystyle\sum^k_{j-0} P_r(r_j)=\displaystyle\sum^k_{j-0} \cfrac{n_j}NSk​=T(rk​)=j−0∑k​Pr​(rj​)=j−0∑k​Nnj​​

    可以得到:
    S0=T(r0)=∑j−0kPr(rj)=0.19S_0=T(r_0)=\displaystyle\sum^k_{j-0} P_r(r_j)=0.19S0​=T(r0​)=j−0∑k​Pr​(rj​)=0.19
    S1=T(r1)=∑j−01Pr(rj)=Pr(r0)+Pr(r1)=0.19+0.25=0.44S_1=T(r_1)=\displaystyle\sum^1_{j-0} P_r(r_j)=P_r(r_0)+P_r(r_1)=0.19+0.25=0.44S1​=T(r1​)=j−0∑1​Pr​(rj​)=Pr​(r0​)+Pr​(r1​)=0.19+0.25=0.44

  4. 根据公式求取像素映射关系

    SS(i)=int(max(pix)−min(pix))∗S(i)+0.5SS(i)=int(max(pix)-min(pix))*S(i)+0.5SS(i)=int(max(pix)−min(pix))∗S(i)+0.5

    这里的pix是指的灰度级,(最大灰度级−最小灰度级)∗累加概率+0.5后取整数(最大灰度级-最小灰度级)*累加概率+0.5后取整数(最大灰度级−最小灰度级)∗累加概率+0.5后取整数

  5. 灰度映射

    找到了原图像和均衡化图像灰度的对应关系,对原图进行操作,将每个像素映射成新的像素

  6. 此时图像均衡化已经完成

公式推导

  • 现假定原图的 直方图-灰度值 关系为 f(x)f(x)f(x),则累积灰度直方图应当是 F(x)F(x)F(x),经过均衡化后的 直方图-灰度值 关系为 f(y)f(y)f(y),其累积灰度直方图应当是 F(y)F(y)F(y)。原灰度值 xxx 与后灰度值 yyy 之间存在某种映射关系:y=T(x)y=T(x)y=T(x)。

    F(y)=P(Y⩽y)=P[T(X)⩽y]=P[X<1T(y)]=F(x)∣x=1T(y)\LARGE{F(y)=P(Y\leqslant y)=P[T(X)\leqslant y]=P\Bigg[X<\cfrac{1}{T(y)}\Bigg]=F(x)\vert_{x=\frac1{T(y)}}}F(y)=P(Y⩽y)=P[T(X)⩽y]=P[X<T(y)1​]=F(x)∣x=T(y)1​​
    F(y)=F[1T(y)]\LARGE{F(y)=F[\frac1{T(y)}]}F(y)=F[T(y)1​]

  • 方程两边对 yyy 求导:

    f(y)=f[1T(y)]⋅[1T(y)]\LARGE{f(y)=f[\frac1{T(y)}]\cdotp [\frac1{T(y)}]}f(y)=f[T(y)1​]⋅[T(y)1​]

    f(y)=f[1T(y)]⋅1d[T(x)]\LARGE{f(y)=f[\frac1{T(y)}]\cdotp \frac1{d[T(x)]}}f(y)=f[T(y)1​]⋅d[T(x)]1​

    f(y)=f[1T(y)]⋅dxdy\LARGE{f(y)=f[\frac1{T(y)}]\cdotp \frac{dx}{dy}}f(y)=f[T(y)1​]⋅dydx​

  • 由于有:

    f(y)=1L−1\LARGE{f(y)=\frac{1}{L-1}}f(y)=L−11​

  • 可得:

    1L−1=f(x)⋅dxdy\LARGE{\frac{1}{L-1}=f(x)\cdotp \frac{dx}{dy}}L−11​=f(x)⋅dydx​

    1L−1⋅dy=f(x)⋅dx\LARGE{\frac{1}{L-1}\cdotp dy=f(x)\cdotp dx}L−11​⋅dy=f(x)⋅dx

  • 方程两边积分:

    1L−1⋅y=∫0xf(x)dx\LARGE{\frac{1}{L-1}\cdotp y=\int^x_0f(x)dx}L−11​⋅y=∫0x​f(x)dx

    y=(L−1)∫0xf(x)dx\LARGE{y=(L-1)\int^x_0f(x)dx}y=(L−1)∫0x​f(x)dx

    T(x)=(L−1)⋅∫0xf(x)dx\LARGE{T(x)=(L-1)\cdotp \int^x_0f(x)dx}T(x)=(L−1)⋅∫0x​f(x)dx

  • 对于离散值而言:

    T(x)=(L−1)MN⋅∫0xf(x)dx\LARGE{T(x)=\frac{(L-1)}{MN}\cdotp \int^x_0f(x)dx}T(x)=MN(L−1)​⋅∫0x​f(x)dx

Matlab 代码实现

直观代码

function strenImg = histogramEqualization(sImg)
% 直方图均衡化[R, C] = size(sImg);% 统计每个像素值出现次数
count = zeros(1, 256);
for i = 1 : Rfor j = 1 : Ccount(1, sImg(i, j) + 1) = count(1, sImg(i, j) + 1) + 1;end
end% 编写T函数
T = zeros(1, 256);
T = double(T);
count = double(count);% 统计每个像素值出现的概率,得到概率直方图
for i = 1 : 256T(1, i) = count(1, i) / (R * C);
end% 求累计概率,得到累计直方图
for i = 2 : 256T(1, i) = T(1, i - 1) + T(1, i);
end% 完善T函数的定义
for i = 1 : 256T(1, i) = T(1, i) * 255;
end% 完成每个像素点的映射
strenImg = double(sImg);
for i = 1 : Rfor j = 1 : CstrenImg(i, j) = T(1, strenImg(i, j) + 1);end
end% 输出仍然要记得改数据类型
strenImg = uint8(strenImg);
end

向量化代码

function strenImg = histogramEqualization(sImg)
% 直方图均衡化[m, n] = size(sImg);
pro = zeros(1, 256);
sum = zeros(1, 256);% 统计每个像素出现次数
for i = 1 : mfor j = 1 : npro(sImg(i, j) + 1) = pro(sImg(i, j) + 1) + 1;      end
endsum(1) = pro(1);% 累计直方图
for g = 2: 256sum(g) = pro(g) + sum(g - 1);
endnewim = zeros(m, n);
% 像素总和
pixSum = m * n;
% 概率分布函数
sum = sum.* 255 / pixSum;for i = 1 : mfor j = 1 : nnewim(i, j) = uint8(sum(sImg(i, j) + 1));if newim(i, j) > 255newim(i, j) = 255;  % 重新分布灰度值endend
endstrenImg = uint8(newim);
end

自适应直方图均衡化(AHE)

  • 自适应直方图均衡化 (Adaptive histgram equalization / AHE)
  • 简述
    • 和普通的直方图均衡算法不同,AHE 算法通过计算图像的局部直方图,然后重新分布亮度来来改变图像对比度。因此,该算法更适合于改进图像的局部对比度以及获得更多的图像细节
    • 不过,AHE 有过度放大图像中相同区域的噪音的问题,限制对比度直方图均衡(CLAHE)算法能有限的限制这种不利的放大。
  • 算法的解释
    • 普通的直方图均衡算法对于整幅图像的像素使用相同的直方图变换,对于那些像素值分布比较均衡的图像来说,算法的效果很好。如果图像中包括明显比图像其它区域暗或者亮的部分,在这些部分的对比度将得不到有效的增强。
    • AHE 算法通过对局部区域执行响应的直方图均衡来改变上述问题。该算法首先被开发出来适用于改进航天器驾驶舱的显示效果。其最简单的形式,就是每个像素通过其周边一个矩形范围内的像素的直方图进行均衡化。均衡的方式则完全同普通的均衡化算法:变换函数同像素周边的累积直方图函数(CDF)成比例。
    • 图像边缘的像素需要特殊处理,因为边缘像素的领域不完全在图像内部。这个通过镜像图像边缘的行像素或列像素来解决。直接复制边缘的像素进行扩充是不合适的,因为这会导致带有剑锋的领域直方图。
  • AHE的属性
    • 领域的大小是该方法的一个参数。领域小,对比度得到增强,领域大,则对比度降低。
    • 当某个区域包含的像素值非常相似,其直方图就会尖状化,此时直方图的变换函数会将一个很窄范围内的像素映射到整个像素范围,这将使得某些平坦区域中的少量噪音经AHE处理后过度放大。

限制对比度直方图均衡(CLAHE)

  • 限制对比度就相当于限制直方图的幅度。

  • 因此我们需要对子块中统计得到的直方图进行裁剪,使其幅值低于某个上限,当然裁剪掉的部分又不能扔掉,我们还需要将这部分裁剪值均匀地分布在整个灰度区间上,以保证直方图总面积不变,如下图:

  • 可以看到,这时直方图又会整体上升了一个高度,会超过我们设置的上限。

  • 其实在具体实现的时候有很多解决方法,可以多重复几次裁剪过程,使得上升的部分变得微不足道,或是用另一种常用的方法:

    • 设裁剪值为ClipLimit,求直方图中高于该值的部分的和totalExcess,此时假设将totalExcess均分给所有灰度级, 求出这样导致的直方图整体上升的高度L=totalExcess/N,以upper=ClipLimit-L为界限对直方图进行如下处理:
    1. 若幅值高于ClipLimit,直接置为ClipLimit
    2. 若幅值处于UpperClipLimit之间,将其填补至ClipLimit
    3. 若幅值低于Upper,直接填补L个像素点
    • 经过上述操作,用来填补的像素点个数通常会略小于totalExcess,也就是还有一些剩余的像素点没分出去,这个剩余来自于 1. 2. 两处。这时我们可以再把这些点均匀地分给那些目前幅值仍然小于ClipLimit的灰度值。
  • 将图像进行分块处理,若每块中的像素点仅通过该块中的映射函数进行变换,则会导致最终图像呈块状效应。

  • 为了解决这个问题,我们需要利用插值运算,也就是每个像素点出的值由它周围4个子块的映射函数值进行双线性插值得到,如下图:

  • 上图中,为了求蓝色像素点处的值,需要利用它周围四个子块的映射函数分别做变换得到四个映射值,再对这四个值做双线性插值即可。

  • 对于边界处的像素点则不是通过四个子块进行插值,如上图红色像素点直接以一个子块的映射函数做变换,绿色像素则以两个子块做映射函数做线性插值。这里讲的边界处像素是指落在图像左上角,左下角、右上角,右下角的四个子块中心像素点围成的四边形之外的像素。如下图,将图像分为8x8子块,边界像素即落在灰色区域的像素点。

直方图均衡化(HE, AHE, CLAHE)相关推荐

  1. 循序渐进之(五)空间域图像增强之自适应直方图均衡化(AHE)

    循序渐进之(五)空间域图像增强之自适应直方图均衡化(AHE) 文字摘自:对比度受限的自适应直方图均衡化(CLAHE) 直方图均衡化(HE)是一种很常用的直方图类方法,基本思想是通过图像的灰度分布直方图 ...

  2. 图像增强—自适应直方图均衡化(AHE)-限制对比度自适应直方图均衡(CLAHE)

    一.自适应直方图均衡化(Adaptive histgram equalization/AHE) 1.简述 自适应直方图均衡化(AHE)用来提升图像的对比度的一种计算机图像处理技术.和普通的直方图均衡算 ...

  3. 限制对比度自适应直方图均衡化算法(CLAHE)实现

    1. 概述 本篇文章是基于这篇博文写的,然后经过粗略查看之后,将其运用到课题中,这里将此记录下来作为记录,文章中若有错误的地方敬请谅解. 2. 实现代码 bool CLAHE_Algorithm::C ...

  4. 基于python的对比度增强(线性变换、直方图正规化、直方图均衡化、CLAHE)

    线性变换 假设输入图像为I,宽为W,高为H,输出图像为O,图像的线性变换可以用以下公式定义: O(r,c)=a×I(r,c)+b,0≤r<H,0≤c<WO(r, c) = a × I(r, ...

  5. OpenCv:直方图均衡化(HE),自适应直方图均衡化(AHE),限制对比度自适应直方图均衡化(CLAHE)

    总结了使用Python OpenCv处理图像直方图均衡化(HE),自适应直方图均衡化(AHE),限制对比度自适应直方图均衡化(CLAHE)的方法. 目录 直方图均衡化(HE) 自适应直方图均衡化(AH ...

  6. 对比度受限自适应直方图均衡化方法

    图像增强技术可具体为时域和频域. 时域增强往往被应用于提高图像的对比度且改进其灰度级, 其原理是在灰度映射转化的基础上, 对像素进行直接性地处理: 频域增强的作用是以强化图像的低. 高频来达到改善图像 ...

  7. Matlab数字图像处理 02 灰度变化(图像直方图、直方图均衡化、直方图匹配)

    第二章 灰度变化 2.1 图像的亮度.对比度和动态范围 2.1.1 亮度 2.1.2 对比度 2.1.3 动态范围 2.2 线性灰度变换 2.2.1 具有饱和处理的线性灰度变换 2.2.2 分段线性灰 ...

  8. OpenCV-Python实战(8)——直方图均衡化

    OpenCV-Python实战(8)--直方图均衡化 0. 前言 1. 灰度直方图均衡化 2. 颜色直方图均衡化 3. 对比度受限的自适应直方图均衡化 4. 比较 CLAHE 和直方图均衡化 5. 直 ...

  9. 十五天掌握OpenCV——直方图均衡化

    魏老师学生--Cecil:学习OpenCV-机器视觉之旅 代码演示 opencv中的直方图均衡化 代码演示 CLAHE有限对比适应性直方图均衡化 代码演示 高质量图像:像素值分布广泛. 直方图均衡化: ...

最新文章

  1. linux centos yum错误 You could try using --skip-broken to work around the problem
  2. 从零开始html css,HTML/CSS从零开始-常用属性(三)
  3. 介绍一种导入文件夹中图片数据集的方法
  4. 面试官:Spring事务的传播行为有几种?
  5. 【每日一包0015】gradient-string
  6. 死锁的四个必要条件,及处理方法
  7. SAP CRM Product Relationship的设计原理
  8. “约见”面试官系列之常见面试题第二十六篇之vue-router的hash和history(建议收藏)
  9. Express 路由、Ejs 、静态文件托管、中间件
  10. mysql慢查询面试题_头条Java岗3面入职:事务+慢查询SQL+Redis+秒杀设计面试题等
  11. 简单使用linux感受,linux小白说说用linux的感受
  12. python课程设计实验报告-python课程设计
  13. minecraft有自带服务器吗,从无到有:一步一步开设Spigot Minecraft服务器
  14. 【规划】常用算法大汇总
  15. 解决Maven打包报错:Failed to clean project: Failed to delete
  16. 组件封装 - steps组件
  17. 编程入门之学哪种编程语言?
  18. 电子信息工程就业方向、就业要求及薪资标准
  19. WinPE_USB启动盘制作
  20. android开发源码下载

热门文章

  1. Python(4)循环嵌套算法及冒泡排序
  2. jq里的event对象
  3. oracle视图转换为mysql视图_oracle视图迁移到mysql
  4. oracle 视图带变量条件,oracle视图(带参数)
  5. openPTrack v2 安装 | 3、OpenPTrack v2 模块编译
  6. Wifi模块-ESP-01s
  7. 一纸学习思维导图 Mind Map
  8. 数字身份_数字身份作为投资
  9. 外文翻译原文附在后面_外文翻译及外文原文(参考格式).doc
  10. SCI与EI检索是什么意思,包括哪些专业?