关于 CLAHE 的理解及实现
CLAHE
CLAHE 是一种非常有效的直方图均衡算法, 目前网上已经有很多文章进行了说明, 这里说一下自己的理解.
CLAHE是怎么来的
直方图均衡是一种简单快速的图像增强方法, 其原理和实现过程以及改进可以查看这里: 一文搞懂直方图均衡_yfor1008-CSDN博客
目前存在一些问题:
- 直方图均衡是全局的, 对图像局部区域存在过亮或者过暗时, 效果不是很好;
- 直方图均衡会增强背景噪声, 如下图所示为 CLAHE 中的示例:

为了解决上述2个问题, 就有2方面的解决方法: 一是解决全局性问题, 二是解决背景噪声增强问题.
- 针对全局性问题: 有人提出了对图像分块的方法, 每块区域单独进行直方图均衡, 这样就可以利用局部信息来增强图像, 这样就可以解决全局性问题;
- 针对背景噪声增强问题: 主要背景增强太过了, 因而有人提出了对对比度进行限制的方法, 这样就可以解决背景噪声增强问题;
将上述二者相结合就是 CLAHE 方法, 其全称为: Contrast Limited Adaptive Histogram Equalization.
CLAHE 算法流程
CLAHE 算法流程主要有以下几个步骤:
- 预处理, 如图像分块填充等;
- 对每个分块处理, 计算映射关系, 计算映射关系时使用了对比度限制;
- 使用插值方法得到最后的增强图像;
其处理流程可以用如下示意图表示:

实现及效果
这里使用matlab实现了该算法, 实现过程参考了: Contrast Limited Adaptive Histogram Equalization (CLAHE) - File Exchange - MATLAB Central (mathworks.com) 及matlab源码 adapthisteq.
以下为几组测试结果:

从左往右以此为: 原图, HE, CLAHE, 从图中可以看到, CLAHE不仅实现了图像细节的增强, 还抑制了背景噪声.

从左往右以此为: 原图, HE, CLAHE, 从图中可以看到, CLAHE实现了对细节的增强且没有使得图像过度增强.
关于关键步骤的说明
关于双线性插值
- 对于每个分块都是将其分成 4 个子块, 然后每个子块于其相邻块的子块重新构成一个分块;
- 对于新构成的块使用双线性插值得到增强后的图像;
- 对于第1行的上面一行子块仅需考虑相邻行的上面一行子块, 最后行, 第1列及最后列同理;
- 对于4个角上的子块, 直接使用本身所在块的映射关系, 不需要进行插值;
如下图所示:

关于限制对比度
CLAHE 中使用的方法是不断地循环, 直到将所有截断后多余的像素都添加到直方图中. 这种方法实现过程比较复杂, 个人认为可以简化, 如:
- 截断后直接丢弃;
- 截断后直接均匀添加到直方图所有的bin上;
上述2种方法对对比度影响不大, 但对图像亮度有一点点影响, 如下图所示为上述方法1与原始CLAHE方法的对比结果, 第1行为原始CLAHE, 第2行为截断后直接丢弃方法, 第1列到第3列使用的截断参数依次为: 0.01, 0.03, 0.05.

从图中可看到, 对图像结果影响较大的参数是截断阈值, 而不是是否将截断后的数据添加到直方图的每个bin上. 如下图所示为另外一组测试结果, 从左到右依次为: 原始图像, 阈值0.01, 阈值0.03, 阈值0.05.

关于预处理
需对图像进行填充, 为方便进行插值, 填充后图像的每个分块都必须为2的整数倍, 要不然不方便对每个块划分为4个子块.
关于直方图分布类型
在查看 matlab 源码时, 里面使用了3种分布类型:
- uniform: CLAHE 使用的方法
- rayleigh: 代码种说是适用于水下(underwater)图像
- exponential: 没有相关说明
这里测试对比了 uniform 和 rayleigh , 如下所示为水下图像测试结果(正常图像测试几乎没有差别, 这里不进行展示了):

从左到右依次为: 原图, uniform 和 rayleigh , 目前没有看出二者的本质区别.
不过这张图像来源: Computer vision algorithm removes the water from underwater images » Behind the Headlines - MATLAB & Simulink (mathworks.com), 作者提出了一种 Sea-thru 方法, 效果不错, 这里下mark一下, 后面有时间在研究研究, 效果如下所示:

参考
- Contrast Limited Adaptive Histogram Equalization (CLAHE) - File Exchange - MATLAB Central (mathworks.com)
- Image Enhancement - CLAHE - 知乎 (zhihu.com)
- CLAHE (Contrast Limited Adaptive Histogram Equalization) (amroamroamro.github.io)
- wangyanckxx/Single-Underwater-Image-Enhancement-and-Color-Restoration: Single Underwater Image Enhancement and Color Restoration, which is Python implementation for a comprehensive review paper "An Experimental-based Review of Image Enhancement and Image Restoration Methods for Underwater Imaging" (github.com)
关于 CLAHE 的理解及实现的更多相关文章
- 图像增强 | CLAHE 限制对比度自适应直方图均衡化
1 基本概述 CLAHE是一个比较有意思的图像增强的方法,主要用在医学图像上面.之前的比赛中,用到了这个,但是对其算法原理不甚了解.在这里做一个复盘. CLAHE起到的作用简单来说就是增强图像的对比度 ...
- 【图像增强】CLAHE 限制对比度自适应直方图均衡化
文章目录: 目录 1 基本概述 2 竞赛中的CLAHE实现 3 openCV绘制直方图 4 对比度Contrast 5 Contrast Stretching 6 Histogram Equaliza ...
- 理解CSS视觉格式化
前面的话 CSS视觉格式化这个词可能比较陌生,但说起盒模型可能就恍然大悟了.实际上,盒模型只是CSS视觉格式化的一部分.视觉格式化分为块级和行内两种处理方式.理解视觉格式化,可以确定得到的效果是应 ...
- 彻底理解AC多模式匹配算法
(本文尤其适合遍览网上的讲解而仍百思不得姐的同学) 一.原理 AC自动机首先将模式组记录为Trie字典树的形式,以节点表示不同状态,边上标以字母表中的字符,表示状态的转移.根节点状态记为0状态,表示起 ...
- 理解加密算法(三)——创建CA机构,签发证书并开始TLS通信
接理解加密算法(一)--加密算法分类.理解加密算法(二)--TLS/SSL 1 不安全的TCP通信 普通的TCP通信数据是明文传输的,所以存在数据泄露和被篡改的风险,我们可以写一段测试代码试验一下. ...
- node.js学习(三)简单的node程序&&模块简单使用&&commonJS规范&&深入理解模块原理
一.一个简单的node程序 1.新建一个txt文件 2.修改后缀 修改之后会弹出这个,点击"是" 3.运行test.js 源文件 使用node.js运行之后的. 如果该路径下没有该 ...
- 如何一步一步用DDD设计一个电商网站(一)—— 先理解核心概念
一.前言 DDD(领域驱动设计)的一些介绍网上资料很多,这里就不继续描述了.自己使用领域驱动设计摸滚打爬也有2年多的时间,出于对知识的总结和分享,也是对自我理解的一个公开检验,介于博客园这个平 ...
- 学习AOP之透过Spring的Ioc理解Advisor
花了几天时间来学习Spring,突然明白一个问题,就是看书不能让人理解Spring,一方面要结合使用场景,另一方面要阅读源代码,这种方式理解起来事半功倍.那看书有什么用呢?主要还是扩展视野,毕竟书是别 ...
- ThreadLocal简单理解
在java开源项目的代码中看到一个类里ThreadLocal的属性: private static ThreadLocal<Boolean> clientMode = new Thread ...
随机推荐
- pom.xml中web.xml is missing and <failOnMissingWebXml> is set to true错误的解决
.personSunflowerP { background: rgba(51, 153, 0, 0.66); border-bottom: 1px solid rgba(0, 102, 0, 1); ...
- 040_Spring注解开发
目录 Spring注解开发 bean注册到Spring容器中 applicationContext.xml添加包扫描注解 实体类添加注解@Component 属性注入 属性添加注解@Value(&qu ...
- 阿里面试Redis常考问题
一提到Redis缓存,我们不得不了解的三个问题就是:缓存雪崩.缓存击穿和缓存穿透.这三个问题一旦发生,会导致大量的请求直接请求到数据库层.如果并发压力大,就会导致数据库崩溃.那p0级的故障是没跑了. ...
- 时间转换 BASIC-14
时间转换 给定一个以秒为单位的时间t,要求用"::"的格式来表示这个时间.表示时间,表示分钟,而表示秒,它们都是整数且没有前导的"0".例如,若t=0,则应输出 ...
- Golang语言系列-03-流程控制语句
Go语言流程控制语句 Go语言中最常用的流程控制语句有 if 和 for ,没有像Python中的while语句.另外,Go语言还有switch和goto语句,不过这两个主要是用来简化代码的,属于扩展 ...
- 【笔记】KNN之网格搜索与k近邻算法中更多超参数
网格搜索与k近邻算法中更多超参数 网格搜索与k近邻算法中更多超参数 网络搜索 前笔记中使用的for循环进行的网格搜索的方式,我们可以发现不同的超参数之间是存在一种依赖关系的,像是p这个超参数,只有在 ...
- HashTable原理和底层实现
1. 概述 上次讨论了HashMap的结构,原理和实现,本文来对Map家族的另外一个常用集合HashTable进行介绍.HashTable和HashMap两种集合非常相似,经常被各种面试官问到两者的区 ...
- mzy对于枚举的理解
关于enum,其实就是简化了的class,功能就是提供一个个独立的.特定含义的常量! 在JDK5.0之前我们想模拟enum的功能,只能使用自定义类的形式: 1.首先私有化构造方法,让外部不能new对象 ...
- 我对数据库关系代数中减法sql实现的思考:mysql脚本
一.创建数据库,创建表结构 CREATE DATABASE Test_sub DEFAULT CHARACTER SET utf8; USE Test_sub; CREATE TABLE studen ...
- 多线程编程<三>
1 /** 2 * 线程的暂停.恢复和停止 3 * @author Administrator 4 * 5 */ 6 public class ThreadControlDemo { 7 public ...