Retinex是一种常用的建立在科学实验和科学分析基础上的图像增强方法。就跟Matlab是由Matrix和Laboratory合成的一样,Retinex也是由两个单词合成的一个词语,他们分别是retina 和cortex,即:视网膜和皮层。Land的retinex模式是建立在以下三个假设之上的:

真实世界是无颜色的,我们所感知的颜色是光与物质的相互作用的结果。我们见到的水是无色的,但是水膜—肥皂膜却是显现五彩缤纷,那是薄膜表面光干涉的结果。
每一颜色区域由给定波长的红、绿、蓝三原色构成的;
三原色决定了每个单位区域的颜色。
Retinex理论的基础理论是物体的颜色是由物体对长波(红色)、中波(绿色)、短波(蓝色)光线的反射能力来决定的,而不是由反射光强度的绝对值来决定的,物体的色彩不受光照非均匀性的影响,具有一致性,即retinex是以色感一致性(颜色恒常性)为基础的。不同于传统的线性、非线性的只能增强图像某一类特征的方法,Retinex可以在动态范围压缩、边缘增强和颜色恒常三个方面达到平衡,因此可以对各种不同类型的图像进行自适应的增强。

原理:

Retinex 理论的基本内容

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

基于Retinex的图像增强的目的就是从原始图像S中估计出光照L,从而分解出R,消除光照不均的影响,以改善图像的视觉效果,正如人类视觉系统那样。

Retinex理论,与降噪类似,该理论的关键就是合理地假设了图像的构成。如果将观察者看到的图像看成是一幅带有乘性噪声的图像,那么入射光的分量就是一种乘性的,相对均匀,且变换缓慢的噪声。Retinex算法所做的就是合理地估计图像中各个位置的噪声,并除去它。

在极端情况下,我们大可以认为整幅图像中的分量都是均匀的,那么最简单的估计照度L的方式就是在将图像变换到对数域后对整幅图像求均值。

Log[R(x,y)] = Log[S(x,y)]-Log[L(x,y)]; 

要求得R(x,y)只需得到L(x,y)即可,但是根据数学的理论,L(x,y)是不能够求得的,只能近似求出。我们用S(x,y)和一个高斯核的卷积来近似表示L(x,y)。所以R(x,y)可用下式表示:

Log(R(x,y))=(Log(S(x,y))-Log(S(x,y)*G(x,y)))

由于R是对数域的输出,要转换为数字图像,必须将他们量化为[0,255]的数字图像范畴,所以要进行线性量化,于是就有了:(G和b)为经验参数

再通过Simplest Color Balance方式,他把数据按照一定的百分比去除最小和最大的部分,然后中间的部分重新线性量化到0和255之间,因为如果直接对MSR处理的结果进行量化,得到的图像往往整体偏灰度,这是由于原始的彩色值经过log处理后的数据范围就比较小了,这样各通道之间的差异也很小,而之后的线性量化比log曲线要平滑很多,因此整体就丧失了彩色。

为此,研究者又开发出一种称之为带色彩恢复的多尺度视网膜增强算法(MSRCR,Multi-Scale Retinex with Color Restoration) ,具体讨论的过程详见 <A Multiscale Retinex for Bridging the Gap Between Color Images and the Human Observation of Scenes>这篇论文,但是论文里为了这个又引入了太多的可调参数,增加了算法的复杂性,不利于自动化实现。

直接从量化的方式上入手,引入了均值和均方差的概念,再加上一个控制图像动态的参数来实现无色偏的调节过程,简要描述如下。

(1)分别计算出 Log[R(x,y)]中R/G/B各通道数据的均值Mean和均方差Var(注意是均方差)。

(2)利用类似下述公式计算各通道的Min和Max值。

Min = Mean - Dynamic * Var;

Max = Mean + Dynamic * Var;
    (3)  对Log[R(x,y)]的每一个值Value,进行线性映射:

R(x,y) = ( Value - Min ) / (Max - Min) * (255-0) ,同时要注意增加一个溢出判断,即:

if (R(x,y) > 255)  R(x,y) =255; else if (R(x,y) < 0) R(x,y)=0;

import cv2
import numpy as np
import mathdef replaceZeroes(data):min_nonzero = min(data[np.nonzero(data)])data[data == 0] = min_nonzeroreturn datadef simple_color_balance(input_img, s1, s2):h, w = input_img.shape[:2]out_img = np.zeros([h, w])sort_img = input_img.copy()one_dim_array = sort_img.flatten()  # 转化为一维数组sort_array = sorted(one_dim_array)  # 对一维数组按升序排序per1 = int((h * w) * s1 / 100)minvalue = sort_array[per1]per2 = int((h * w) * s2 / 100)maxvalue = sort_array[(h * w) - 1 - per2]# 实施简单白平衡算法if (maxvalue <= minvalue):for i in range(h):for j in range(w):out_img[i, j] = maxvalueelse:scale = 255.0 / (maxvalue - minvalue)for m in range(h):for n in range(w):if (input_img[m, n] < minvalue):out_img[m, n] = 0elif (input_img[m, n] > maxvalue):out_img[m, n] = 255else:out_img[m, n] = scale * (input_img[m, n] - minvalue)  # 映射中间段的图像像素out_img = cv2.convertScaleAbs(out_img)return out_img
def MSRCR(img, scales, s1, s2):h, w = img.shape[:2]# print(h, w)scles_size = len(scales)img = np.array(img, dtype=np.float64)# print(img)log_R = np.zeros((h, w), dtype=np.float64)img_sum = np.add(img[:,:,0],img[:,:,1],img[:,:,2])# print(img_sum)# print("11111111111111111111111111111111")img_sum = replaceZeroes(img_sum)# print(img_sum)gray_img = []for j in range(3):img[:, :, j] = replaceZeroes(img[:, :, j])for i in range(0, scles_size):L_blur = cv2.GaussianBlur(img[:, :, j], (scales[i], scales[i]), 0)L_blur = replaceZeroes(L_blur)dst_img = cv2.log(img[:, :, j])dst_Lblur = cv2.log(L_blur)# dst_ixl = cv2.multiply(dst_img, dst_Lblur)log_R += cv2.subtract(dst_img, dst_Lblur)# print(i)# print(scles_size)MSR = log_R / 3.0'''img_sum_log = np.zeros((h, w))for i in range(0, h):for k in range(0, w):img_sum_log[i,k] = 125.0*math.log(img[i,k,j]) - math.log(img_sum[i,k])MSRCR = MSR * (img_sum_log[:, :])print(img_sum)# x = cv2.log(img_sum)'''MSRCR = MSR * (cv2.log(125.0 * img[:, :, j]) - cv2.log(img_sum))gray = simple_color_balance(MSRCR, s1, s2)gray_img.append(gray)return gray_imgif __name__ == '__main__':scales = [15, 101, 301]s1, s2 = 2,3src_img = cv2.imread('4.jpg')src_img = cv2.cvtColor(src_img, cv2.COLOR_BGR2RGB)cv2.imshow('img', src_img)MSRCR_Out = MSRCR(src_img, scales, s1, s2)result = cv2.merge([MSRCR_Out[0], MSRCR_Out[1], MSRCR_Out[2]])cv2.imshow('MSR_result', result)cv2.waitKey(0)cv2.destroyAllWindows()

————————————————
版权声明:本文为CSDN博主「SongpingWang」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

致谢:
https://blog.csdn.net/wsp_1138886114/article/details/83096109

带色彩恢复的多尺度视网膜增强算法(MSRCR)的原理、实现及应用。 - Imageshop - 博客园 (cnblogs.com)

Retinex图像增强相关推荐

  1. 关于Retinex图像增强算法的一些新学习

    关于Retinex图像增强算法的一些新学习. - Imageshop 时间 2014-06-26 16:50:00  博客园精华区 原文  http://www.cnblogs.com/Imagesh ...

  2. OpenCV图像增强(二)——Retinex图像增强

    前言 1.Retinex图像增强是一种高动态范围图像的新色调映射技术.而基础理论是,物体的颜色是由物体对长波(红色).中波(绿色).短波(蓝色)光线的反射能力来决定的,而不是由反射光强度的绝对值来决定 ...

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

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

  4. Retinex图像增强算法——SSR,MSR,MSRCR,MSRCP,autoMSRCR

    系列文章目录 关于OpenCV的一些图像处理函数 图象基本操作(读取.显示.通道提取.边界填充.融合.保存) Retinex图像增强算法--SSR,MSR,MSRCR,MSRCP,autoMSRCR ...

  5. 荔枝hsv空间图像分割程序matlab,基于Retinex图像增强的不同光照条件下的成熟荔枝识别_熊俊涛...

    第29卷第12期农业工程学报V ol.29 No.12 170 2013年6月Transactions of the Chinese Society of Agricultural Engineeri ...

  6. matlab Retinex图像增强算法

    Retinex理论在彩色图像增强.图像去雾.彩色图像恢复方面拥有很好的效果,下面介绍一下我对该算法的理解. Retinex理论 Retinex理论始于Land和McCann于20世纪60年代作出的一系 ...

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

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

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

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

  9. 图像去雾(二)Retinex图像增强算法

    前一段时间研究了一下图像增强算法,发现Retinex理论在彩色图像增强.图像去雾.彩色图像恢复方面拥有很好的效果,下面介绍一下我对该算法的理解. Retinex理论 Retinex理论始于Land和M ...

最新文章

  1. SLAM学习--帝国理工学院机器人课程slam部分讲义(附下载链接)
  2. 减小TabLayout高度而不影响每个tab展示的几种方法
  3. .net中自定义过滤器对Response内容进行处理
  4. long logn的大小c语言,基本排序(C语言版) - ________MX的个人页面 - OSCHINA - 中文开源技术交流社区...
  5. groovy lambda_Java Lambda流和Groovy Clouse的比较
  6. 使用栈来完成一个表达式的结果
  7. Selenium不打开浏览器采爬取数据 Java
  8. 基于C#+AE的地图要素的添加(比例尺、指北针、图例)
  9. java7 新特性官方介绍_java7 新特性 总结版
  10. python定时重启程序
  11. 电脑无线网卡安装不了驱动怎么办?
  12. 寻找 Symbian 编码(三)
  13. C语言网络编程:recv函数详解
  14. 微软雅黑和consolas混合字体_你用的字体得到授权了吗,小心巨额索赔!
  15. 小米蓝牙广播数据解析(MiBeacon)
  16. 线性回归、岭回归、逻辑回归、聚类
  17. bim oracle,IBMS和BIM的融合之路
  18. C-V2X技术发展、应用及展望
  19. 【Spring之轨迹】结合 @Scheduled 实现定时将 Redis 缓存刷入数据库(配 Redis 工具类与例子实战)
  20. [批量主机存活扫描工具scanhost]扫描主机存活[python版本,非nmap版本]

热门文章

  1. 游龙传说服务器维护,3月15日维护:渡劫后155可传说
  2. Codemeter安装器遇到了一个错误,导致安装失败,请联系软件制造商以获得帮助
  3. Qt Creator介绍 使用教程
  4. 【Keras+计算机视觉+Tensorflow】生成对抗神经网络中DCGAN、CycleGAN网络的讲解(图文解释 超详细)
  5. GOIP connects with Elastix through “config by line”
  6. Python3 中的 cmp_to_key 函数
  7. 模型可解释性-shap value
  8. 远征日服·信喵之野望 按键精灵脚本4.截卡
  9. C++实现otsu算法
  10. 线性代数 --- 如何用行向量和列向量对矩阵进行操作?