引言

始于Edwin Herbert Land(埃德温·赫伯特·兰德)于1971年提出的一种被称为色彩恒常的理论,并基于此理论的图像增强方法。Retinex这个词由视网膜(Retina)和大脑皮层(Cortex)合成而来.之所以这样设计,表明Land他也不清楚视觉系统的特性究竟取决于此两个生理结构中的哪一个,抑或两者都有关系。不同于传统的图像增强算法,如线性、非线性变换、图像锐化等只能增强图像的某一类特征,如压缩图像的动态范围,或增强图像的边缘等,Retinex可以在动态范围压缩、边缘增强和颜色恒常三方面达到平衡,可以对各种不同类型的图像进行自适应性地增强,在很多方面得到了广泛的应用。

算法概述

Retinex 理论的基本内容是物体的颜色是由物体对长波(红)、中波(绿)和短波(蓝)光线的反射能力决定的,而不是由反射光强度的绝对值决定的;物体的色彩不受光照非均性的影响,具有一致性,即Retinex理论是以色感一致性(颜色恒常性)为基础的。如下图所示,观察者所看到的物体的图像S是由物体表面对入射光L反射得到的,反射率R由物体本身决定,不受入射光L变化。

对于观察图像S,有公式表示为:

S(x,y)=R(x,y)L(x,y)(1)

其中, L(x,y)表示亮度分量, R(x,y)表示物体反射分量, S(x,y)表示观测到的图像。
Retinex理论增强算法的思想就是利用式(1),去除亮度分量 L求得反射分量 R,从而达到图像增强效果。
对(1)式两边取对数

log(S(x,y))=log(L(x,y))+log(R(x,y))(2)

由(2)得

log(R(x,y))=log(S(x,y))−log(L(x,y))(3)

由式(3)可知,只需要估计亮度分量 L就能求得反射分量,因此L的估计直接决定图像恢复效果.Jobson等论证了高斯卷积函数可以从已知图像 S中更好地估计出亮度分量,即

L(x,y)=S(x,y)∗G(x,y)(4)

其中,’*’代表卷积操作,高斯函数 G(x,y)=k⋅exp(−x2+y2σ2), σ是高斯函数尺度参数, k为归一化因子,使 ∬G(x,y)dxdy=1。对于RGB彩色图像的某一个通道,

log(Rc(x,y))=log(Sc(x,y))−log(Sc(x,y))∗G(x,y)(5)

其中, c表示RGB3个通道的某一个通道; σ 为尺度函数,取值大时,颜色失真小但细节恢复差,取值小时,细节恢复好,但颜色失真大。
为弥补SSR算法不足,MSR算法对每一个通道进行3次不同尺度滤波,加权求和,处理时间也会变长,且使用不同的尺度,导致恢复的RGB比值与原图比值不太一样,颜色失真。

log(R(x,y))=Weight1⋅log(Rσ1(x,y))+Weight2⋅log(Rσ2(x,y))+Weight3⋅log(Rσ3(x,y))(6)

Rehman等提出MSRCR算法,引入分量比值调整因子从而降低色彩失真的影响。

RMSRCR(x,y)=C(x,y)RMSR(x,y)(7)

其中 C(x,y)=G{log[αIc(x,y)]−log[∑c=13Ic(x,y)]}。

流程

  1. 按照(4)式,计算入射分量L;
  2. 按照(3)式,计算单一尺度下的log(Rσ(x,y));
  3. 按照(6)式,对不同尺度进行加权求和;
  4. 按照(7)式,进行色彩恢复;
  5. 将RMSRCR量化为0到255范围,输出。

入射分量获取

Retinex算法核心在于入射分量的获取,简单来说,这个可以对原图像进行高斯卷积获取。当图像比较大的时候,其计算过程是非常复杂的,O(MNPQ),M,N是原图像的高度和宽度,P,Q是卷积核大小。实现的时候可以使用递归高斯滤波,复杂度O(MN)(参见paper:Recursive implementation of the Gaussian filter,源码在GIMP中有)。下面我给出在3种不同尺度下获取的亮度图,等分权重。

色彩恢复

GIMP中色彩恢复代码如下:

<pre name="code" class="cpp">/*  Final calculation with original value and cumulated filter values.  The parameters gain, alpha and offset are constants.  */   /* Ci(x,y)=log[a Ii(x,y)]-log[ Ei=1-s Ii(x,y)] */   alpha  = 128.0f;   gain   = 1.0f;   offset = 0.0f;   for ( i = 0; i < size; i += bytes )   {   float logl;   psrc = src+i;   pdst = dst+i;   logl = (float)log( (float)psrc[0] + (float)psrc[1] + (float)psrc[2] + 3.0f );   pdst[0] = gain * ((float)(log(alpha * (psrc[0]+1.0f)) - logl) * pdst[0]) + offset;   pdst[1] = gain * ((float)(log(alpha * (psrc[1]+1.0f)) - logl) * pdst[1]) + offset;   pdst[2] = gain * ((float)(log(alpha * (psrc[2]+1.0f)) - logl) * pdst[2]) + offset;   }

另外,最后一步代码又增加了调节项,用于控制饱和度和颜色,最后将其量化到[0~255],详细代码如下。

 <pre name="code" class="cpp">  /*  Adapt the dynamics of the colors according to the statistics of the first and second order.  The use of the variance makes it possible to control the degree of saturation of the colors.  */   pdst = dst;compute_mean_var( pdst, &mean, &var, size, bytes );   mini = mean - rvals.cvar*var;   maxi = mean + rvals.cvar*var;   range = maxi - mini;   if ( !range ) range = 1.0;   for ( i = 0; i < size; i+= bytes )   {   psrc = src + i;   pdst = dst + i;   for (j = 0 ; j < 3 ; j++)   {   float c = 255 * ( pdst[j] - mini ) / range;   psrc[j] = (unsigned char)clip( c, 0, 255 );   }   }   free (dst);

效果

我依据GIMP中插件contrast-retinex.c用Matlab实现了一遍,效果如下

宽动态图像


水下图像


低照度图像

雾天图像


评论

Retinex算法在图像增强诸多领域应用广泛,如上述宽动态图像增强,水下图像增强,雾天图像增强,低照度图像增强等等,更多可以参考NASA关于Retinex的介绍。Retinex的实现,C语言用了递归高斯滤波器,我不知道Matlab是否有对应的函数,我在这里是将图像转换到频率域高斯低通滤波处理的,因此算法时间耗费也并不大。OpenCV版本的Retinex算法已传到CSDN上共享,下载请点击这里,记得给好评哦。

更多阅读

http://dragon.larc.nasa.gov/
http://www.cnblogs.com/Imageshop/archive/2013/04/17/3026881.html
A multiscale retinex for bridging the gap between color images and the human observation of scenes

转载请保留以下信息

作者 日期 联系方式
风吹夏天 2015年5月13日 wincoder@qq.com

MSRCR(Multi-Scale Retinex with Color Restore)相关推荐

  1. MSRCR(Multi-Scale Retinex with Color Restore)多尺度Retinex图像增强

    引言 始于Edwin Herbert Land(埃德温·赫伯特·兰德)于1971年提出的一种被称为色彩恒常的理论,并基于此理论的图像增强方法.Retinex这个词由视网膜(Retina)和大脑皮层(C ...

  2. java语义事件的含义_Java基础之处理事件——应用程序中的语义事件监听器(Sketcher 5 with element color listeners)...

    控制台程序. 为了标识元素的类型,可以为菜单已提供的4中元素定义常量,用作ID.这有助于执行菜单项监听器的操作,还提供了一种标识颜色类型的方式.我们会累积许多应用程序范围的常量,所以把它们定义为可以静 ...

  3. MDNet(multi domain CNN用于视觉跟踪)--源代码详解--mdnet_features_fcX.m

    该函数,输入全连接网络的网络参数.卷积层网络的输出,计算全连接网络的计算结果,源文件如下: function [ feat ] = mdnet_features_fcX(net, ims, opts) ...

  4. Part I 空气曲棍球 Chapter4 (4.4 Rendering with the New Color Attribute)

    4.4 使用新的颜色进行渲染(Rendering with the New Color Attribute) 现在我们已经在顶点数据中增加了一个颜色属性数据并且已经更新了相应的顶点着色器及片元着色器, ...

  5. 基于色彩恒常( color constancy)特性的Frankle-McCann Retinex图像增强。

    from:https://www.cnblogs.com/Imageshop/archive/2013/04/18/3029352.html 基于色彩恒常( color constancy)特性的Fr ...

  6. 基于色彩恒常( color constancy)特性的Frankle-McCann Retinex图像增强

    从历史的顺序上讲,本篇应该放在MSRCR之前的,只是由于现在大多论文都是描述的MSRCR,因此我也是先学习MSRCR的. 今天,无意中找寻一些Retinex资料,搜索到一篇文章<Retinex ...

  7. 《MA‑CRNN: a multi‑scale attention CRNN for Chinese text line recognition in natural scenes》论文阅读

    参考博文: CRNN的一个变种,可以读一读,看看相对于CRNN来说有什么变化?以及为什么? 文章目录 make decision step1:读摘要 step2:读Introduction step3 ...

  8. origin绘制投影能带-颜色渐变图(color Mapped)

    将得到的投影能带数据直接拖入origin中,比如vasp中利用命令'vaspkit -task 213'可获取投影能带的数据. vaspkit -task 213 选中三列数据,第一列是k点坐标,第二 ...

  9. Redis 笔记(08)— 事务(一次执行多条命令、命令 watch/multi/exec/discard、错误处理)

    1. 事务概念 Redis 中的事务 (transaction)是一组命令的集合.事务同命令一样是 Redis 的最小执行单位,一个事务中的命令要么都执行,要么都不执行.事务的原理是先将属于一个事务的 ...

  10. Android 中一些常用类的常用方法(Math、Random、Color、Paint、Canvas、Bitmap、BitmapFactory)...

    1.java.lang.Math类常用的常量和方法: Math.PI 记录的圆周率 Math.E 记录e的常量 Math.abs 求绝对值 Math.sin 正弦函数 Math.asin 反正弦函数 ...

最新文章

  1. Win64 驱动内核编程-21.DKOM隐藏和保护进程
  2. Silverlight与JavaScript通信
  3. 质子交换膜燃料电池稳压器的设计及仿真
  4. SQL 2008 外网访问说明
  5. 操作系统已经向SQL Server 返回了错误21
  6. AI公开课丨钱铁云:面向复杂和低资源环境的方面级情感分析
  7. 1.2、Mybatis二级缓存测试
  8. thinkphp路径引用问题
  9. 清华大学操作系统OS学习(八)——虚拟存储概念
  10. AVEVA PDMS 二次开发之PML语言基础 21/10/21 01.0.02
  11. jsp中的property
  12. 注册表编辑已经被您的系统管理员停用
  13. 解读翻译李飞飞-Hiding Data With Deep Networks
  14. 2020四川大学计算机考研真题,2020年四川大学计算机考研初试874真题回忆!
  15. C++关于引用的分析
  16. 机器学习cae_关于CAE 仿真对HPC需求的迷思-Part 1
  17. 微信支付交易查询案例
  18. php版临时邮箱,Forsaken Mail创建临时邮箱系统| 手把手教程
  19. python apache benchmark_Python cudnn.benchmark方法代码示例
  20. 取中文拼音首字母,提供了多音字的选择 js javascript c# java(转)

热门文章

  1. C++11 enable_shared_from_this
  2. opendir是安全重入函数吗_redis实现分布式锁,与jdk可重入锁ReentrantLock的原理对比剖析...
  3. for命令linux,linux命令:for循环(示例代码)
  4. kruskal java_kruskal算法 源码(java)
  5. 度量相似性数学建模_相似性指数 (2)
  6. SpringBoot:java.lang.NullPointerException
  7. Go基础:函数与方法的区别
  8. JavaWeb:Ajax和JSON
  9. SQL:pgsql插入数据
  10. java 数据库按钮跳转_java,数据库的连接及基本操作