Retinex图像增强算法

article/2025/11/7 15:17:33

                                            Retinex图像增强算法

 

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

  • 真实世界是无颜色的,我们所感知的颜色是光与物质的相互作用的结果。我们见到的水是无色的,但是水膜—肥皂膜却是显现五彩缤纷,那是薄膜表面光干涉的结果。
  • 每一颜色区域由给定波长的红、绿、蓝三原色构成的;
  • 三原色决定了每个单位区域的颜色。

Retinex理论的基础理论是物体的颜色是由物体对长波(红色)、中波(绿色)、短波(蓝色)光线的反射能力来决定的,而不是由反射光强度的绝对值来决定的,物体的色彩不受光照非均匀性的影响,具有一致性,即retinex是以色感一致性(颜色恒常性)为基础的。不同于传统的线性、非线性的只能增强图像某一类特征的方法,Retinex可以在动态范围压缩、边缘增强和颜色恒常三个方面达到平衡,因此可以对各种不同类型的图像进行自适应的增强。

40多年来,研究人员模仿人类视觉系统发展了Retinex算法,从单尺度Retinex算法,改进成多尺度加权平均的MSR算法,再发展成彩色恢复多尺度MSRCR算法

一. 单尺度SSR(Single Scale Retinex)

1. 原理

一幅给定的图像S(x,y)可以分解为两个不同的图像:反射图像R(x,y)和入射图像(也有人称之为亮度图像)L(x,y),其原理图如下所示:
 

如上图所示,图像可以看做是入射图像和反射图像构成,入射光照射在反射物体上,通过反射物体的反射,形成反射光进入人眼。最后形成的图像可以如下公式表示:

                                                  I(x,y)=L(x,y)*R(x,y) (乘,非卷积)  (1-1)

  式中: I(x,y)代表被观察或照相机接收到的图像信号;L(x,y)代表环境光的照射分量 ;R(x,y)表示携带图像细节信息的目标物体的反射分量 。

  将(1-1)式两边取对数,则可抛开入射光的性质得到物体的本来面貌,即有关系式 :

                                               Log[R(x,y)] = Log[I(x,y)]-Log[L(x,y)];      (1-2)

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

                                                  Log(R(x,y))=(Log(I(x,y))-Log(I(x,y)*G(x,y)))  (1-3)

上式中*代表卷积,G(x,y)代表高斯核,最后我们看到的图像是对R(x,y)映射到[0,255]上的结果,一般取线性映射。

所以,笼统的讲,Retinex算法是去掉光照的影响,还原图像的本来面目。

对上面的理论的进行一个简单的注释吧。把这个技术运用到图像处理上,就是针对我们现在已经获得的一副图像数据I(x,y),计算出对应的R(x,y),则R(x,y)认为是增强后的图像,现在的关键是如何得到L(X,Y)。Retinex理论的提出者指出这个L(x,y)可以通过对图像数据I(x,y)进行高斯模糊而得到,很多论文中都列出了那个中心/围绕函数以及需要归一化的K值,搞的很多新手都不明白是什么了,其实就是一个模糊而已。从实际运用的角度来说,也可以用均值模糊来代替高斯模糊。

     因此这个算法的细路就很简单了,具体步骤如下:

     1、输入: 原始图像数据I(x,y),尺度(也就是所谓的模糊的半径)

     2、处理:(1) 计算原始图像按指定尺度进行模糊后的图像 L(x,y);

              (2) 按照2-2式的计算方法计算出 Log[R(x,y)]的值。

              (3) 将 Log[R(x,y)]量化为0到255范围的像素值,作为最终的输出。

可以看得出,算法很简单,其核心的东西还是在于高斯模糊的实现。关于高斯模糊,网上有很多快速优化的文章参考,具体的参考代码可能很少有好人提供的。

注意到一点,似乎在量化的时候没有谁会将 Log[R(x,y)]进行Exp函数的运算而直接得到R(x,y),至于为什么,我无法给出明确的答案。

量化的方式其实有很多种,而这个方法在很大的程度上对处理的效果有着决定性的影响。至今我没看到有哪一篇论文对这一块讲的很清楚,也不知道他们的那些结果是如何取得的,一种最简单的方式就是计算出Log[R(x,y)]的最大值Max和最小值Min,然后对每一个值Value,进行线性量化,公式为:

                                            R(x,y) = ( Value - Min ) / (Max - Min) * (255-0)      (1-4)

SSR:

#SSRdef replaceZeroes(data):min_nonzero = min(data[nonzero(data)])data[data == 0] = min_nonzeroreturn datadef SSR(img,size):L_blur = cv2.GaussianBlur(img,(size,size),0)eps = float(1e-10)h,w = img.shape[:2]dst_img = zeros((h,w),dtype = float32)dst_Lblur = zeros((h, w),dtype=float32)dst_R = zeros((h, w), dtype=float32)img = replaceZeroes(img)L_blur = replaceZeroes(L_blur)cv2.log(img,dst_img)cv2.log(L_blur,dst_Lblur)log_R = cv2.subtract(dst_img,dst_Lblur)cv2.normalize(log_R,dst_R,0,255,cv2.NORM_MINMAX)log_uint8 = cv2.convertScaleAbs(dst_R)minvalue,maxvalue,minloc,maxloc = cv2.minMaxLoc(log_R)for i in range(h):for j in range(w):log_R[i,j] = (log_R[i,j]-minvalue)*255.0/(maxvalue-minvalue)log_uint8 = cv2.convertScaleAbs(log_R)return log_uint8

二. 多尺度MSR(Multi-Scale Retinex)

MSR是在SSR基础上发展来的,优点是可以同时保持图像高保真度与对图像的动态范围进行压缩的同时,MSR也可实现色彩增强、颜色恒常性、局部动态范围压缩、全局动态范围压缩,也可以用于X光图像增强。

为了得到更好的效果,人们又开发出所谓的多尺度视网膜增强算法(MSR, Multi-Scale Retinex),最为经典的就是3尺度的,大、中、小,既能实现图像动态范围的压缩,又能保持色感的一致性较好。同单尺度相比,该算法有在计算Log[R(x,y)]的值时步骤有所不同:

(1)需要对原始图像进行每个尺度的高斯模糊,得到模糊后的图像Li(x,y),其中小标i表示尺度数。

(2) 对每个尺度下进行累加计算

Log[R(x,y)] =  Log[R(x,y)] + Weight(i)* ( Log[Ii(x,y)]-Log[Li(x,y)]);  

其中Weight(i)表示每个尺度对应的权重,要求各尺度权重之和必须为1,经典的取值为等权重。

其他的步骤和单尺度的没有区别。

为表述方便,还是贴出其基本的计算原理:

上式中,I为原始输入图像,F是滤波函数,一般为高斯函数,N为尺度的数量,W为每个尺度的权重,一般都为1/N, R表示在对数域的图像的输出。

MSR

#MSR
def replaceZeroes(data):min_nonzero = min(data[nonzero(data)])data[data == 0] = min_nonzeroreturn datadef MSR(img, scales):weight = 1/3.0scales_size = 3h, w = img.shape[:2]dst_img = zeros((h, w), dtype=float32)dst_Lblur = zeros((h, w), dtype=float32)dst_R = zeros((h, w), dtype=float32)log_R = zeros((h, w), dtype=float32)for i in range(0,scales_size):img = replaceZeroes(img)L_blur = cv2.GaussianBlur(img, (scales[i], scales[i]), 0)L_blur = replaceZeroes(L_blur)cv2.log(img, dst_img)cv2.log(L_blur, dst_Lblur)log_R += weight*cv2.subtract(dst_img, dst_Lblur)cv2.normalize(log_R, dst_R, 0, 255, cv2.NORM_MINMAX)log_uint8 = cv2.convertScaleAbs(dst_R)return log_uint8

三. 带色彩恢复的多尺度MSR(Multi-Scale Retinex with Color Restoration)

  由于R是对数域的输出,要转换为数字图像,必须将他们量化为[0,255]的数字图像范畴,关于这个量化的算法,有这极为重要的意义,他的好坏直接决定了最终输出的图像的品质。

  目前,结合上述文章中提出的一些过程,有4种方式进行处理:

  第一种,也是最容易想到的就是,直接线性量化,即采用下式进行处理:

  这种方式,由于Retinex数据处理后的高动态特性,数据分布很广,会出现严重的两极化现象,一般难以获得满意的结果。

  第二种,就是在经典的MSRCR文章《A Multiscale Retinex for Bridging the Gap Between Color Images and the Human Observation of Scenes》中提出的Canonical Gain/set 算法。计算公式如:

    

    

  其中G和b为经验参数。

  第三种,实在上述文章中提到的Simplest Color Balance(我简写为SCR)方式,这种方式的处理类似于Photoshop中的自动色阶,他把数据按照一定的百分比去除最小和最大的部分,然后中间的部分重新线性量化到0和255之间。

  第四种,就是GIMP的Retinex算法,这个可详见 带色彩恢复的多尺度视网膜增强算法(MSRCR)的原理、实现及应用 一文的描述。

  还有一种方式,就是大家知道HDR的过程吧,他也是将高动态的数据量化到图像的可视范围,因此可以直接将这类算法应用与这个问题上。我也做了实验,效果似乎一般。

  在用第二种或第三种方式处理时,最好还需要有个Color Restoration的过程,因为如果直接对MSR处理的结果进行量化,得到的图像往往整体偏灰度,这是由于原始的彩色值经过log处理后的数据范围就比较小了,这样各通道之间的差异也很小,而之后的线性量化比log曲线要平滑很多,因此整体就丧失了彩色。

论文中提出了修正方式如下:

          

          

          

 

   其中β=46,α=125为经验参数,但是最终我的分析认为β不可能取这么大,取1试验表明效果还不错。

   对于一些原始图像HUE较为合理的图,如果用经典的MSRCR算法,会导致处理后的图容易偏色,上述论文提出了对图像的Intensity数据进行Retinex处理,然后再把数据根据原始的RGB的比例映射到每个通道,这样就能在保留原始颜色分布的基础上增强图像,文章中称其为MSRCP。

MSRCR算法步骤:

MSRCR实现

#MSRCR
def replaceZeroes(data):min_nonzero = min(data[nonzero(data)])data[data == 0] = min_nonzeroreturn data#simple color balance
def simple_color_balance(input_img,out_img,s1,s2):h,w = input_img.shape[:2]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)def MSRCR(img,MSRCR_Out,scles,s1,s2):h,w = img.shape[:2]scles_size = 3epc = float(1e-4)B = img[:,:,0]G = img[:, :, 1]R = img[:, :, 2]dst_img = zeros((h, w), dtype=float32)dst_Lblur = zeros((h, w), dtype=float32)log_R = zeros((h, w), dtype=float32)I =  zeros((h, w), dtype=float32)I = (B+G+R)I = replaceZeroes(I)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)cv2.log(img[:, :, j], dst_img)cv2.log(L_blur, dst_Lblur)log_R += cv2.subtract(dst_img, dst_Lblur)MSR = log_R / 3.0MSRCR = MSR*(cv2.log(125.0*img[:, :, j]) - cv2.log(I))simple_color_balance(MSRCR,MSRCR_Out[:,:,j],s1,s2)

MSRCP算法:

MSRCP实现:

##MSRCP
def replaceZeroes(data):#这个函数主要是防止取对数的时候,出现去穷小的结果min_nonzero = min(data[nonzero(data)])data[data == 0] = min_nonzeroreturn data#simple color balance
def simple_color_balance(input_img,out_img,s1,s2):h,w = input_img.shape[:2]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)#映射中间段的图像像素def MSRCP(img,scles,s1,s2):h,w = img.shape[:2]scles_size = 3epc = float(1e-4)B_chan = img[:,:,0]G_chan = img[:, :, 1]R_chan = img[:, :, 2]dst_img = zeros((h, w), dtype=float32)dst_Lblur = zeros((h, w), dtype=float32)log_R = zeros((h, w), dtype=float32)I =  zeros((h, w), dtype=float32)Int1 = zeros((h, w), dtype=float32)R_channel_out = zeros((h, w), dtype=float32)G_channel_out = zeros((h, w), dtype=float32)B_channel_out = zeros((h, w), dtype=float32)MSRCP_Out_img = zeros(img.shape, dtype=float32)MSRCP_Out = zeros(img.shape, dtype=uint8)I = (B_chan+G_chan+R_chan)/3.0I = replaceZeroes(I)for i in range(0, scles_size):L_blur = cv2.GaussianBlur(I, (scales[i], scales[i]), 0)L_blur = replaceZeroes(L_blur)cv2.log(I, dst_img)cv2.log(L_blur, dst_Lblur)log_R += (dst_img - dst_Lblur)MSR = log_R / 3.0simple_color_balance(MSR,Int1,s1,s2)for i in range(h):for j in range(w):maxtmp = max(B_chan[i,j],G_chan[i,j])B = max(maxtmp,R_chan[i,j])if(I[i,j] == 0):I[i, j] = 1A = min(255/B,Int1[i,j]/I[i,j])R_channel_out[i,j] = A*R_chan[i,j]G_channel_out[i, j] = A * G_chan[i, j]B_channel_out[i, j] = A * B_chan[i, j]MSRCP_Out_img = cv2.merge([B_channel_out,G_channel_out,R_channel_out])MSRCP_Out = cv2.convertScaleAbs(MSRCP_Out_img)return MSRCP_Out

四. 图像效果

 

Original

SSR

 

MSR

              从上到下分别是原始图、SSR、MSR、MSRCR、MSRCP,其中多尺度图像中的尺度因子都是15,101,301

 参考文献:

关于Retinex图像增强算法的一些新学习。作者: laviewpbt   时间: 2014.6.26    联系QQ:  1664462947

Retinex图像增强算法(SSR, MSR, MSRCR)详解及其OpenCV源码

msrcr(Multi-Scale Retinex with Color Restoration) 带色彩恢复的多尺度视网膜增强算法 整理

Multiscale Retinex

 

 

 

 

 


http://chatgpt.dhexx.cn/article/4ik6OyFf.shtml

相关文章

图像增强算法Python实现之Retinex(含代码)

Retinex是一种常用的建立在科学实验和科学分析基础上的图像增强方法&#xff0c;它是Edwin.H.Land于1963年提出的。就跟Matlab是由Matrix和Laboratory合成的一样&#xff0c;Retinex也是由两个单词合成的一个词语&#xff0c;他们分别是retina 和cortex&#xff0c;即&#xff…

Retinex图像增强

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

图像处理:Retinex算法

目录 前言 概念介绍 Retinex算法理论 单尺度Retinex&#xff08;SSR&#xff09; 多尺度Retinex&#xff08;MSR&#xff09; 多尺度自适应增益Retinex&#xff08;MSRCR&#xff09; Opencv实现Retinex算法 SSR算法 MCR算法 MSRCR算法 效果展示 总结 参考文章 前…

Retinex

Retinex图像增强算法 前一段时间研究了一下图像增强算法&#xff0c;发现Retinex理论在彩色图像增强、图像去雾、彩色图像恢复方面拥有很好的效果&#xff0c;下面介绍一下我对该算法的理解。 Retinex理论 Retinex理论始于Land和McCann于20世纪60年代作出的一系列贡献,其基本思…

Retinex算法详解

Retinex是一种常用的建立在科学实验和科学分析基础上的图像增强方法&#xff0c;它是Edwin.H.Land于1963年提出的。就跟Matlab是由Matrix和Laboratory合成的一样&#xff0c;Retinex也是由两个单词合成的一个词语&#xff0c;他们分别是retina 和cortex&#xff0c;即&#xff…

关于Retinex理论的一些理解

目前一直在参与关于Retinex的相关课题&#xff0c;并完成了许多模型的构建&#xff0c;本文以个人的见解介绍Retinex的相关理论 1. 基本原理 Retinex理论是上世纪八十年代由land等人提出的算法。该理论认为人眼可以感知近似一致的色彩信息&#xff0c;这种性质称为色彩…

Retinex理解

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

Retinex理论,单尺度Retinex、多尺度Retinex(MSR)、带颜色恢复的多尺度 Retinex(MSRCR)原理

1、Retinex理论 Retinex 是两个单词合成的&#xff0c;它们分别是 retina &#xff08;视网膜&#xff09;和 cortex &#xff08;皮层&#xff09;&#xff0c;因此 Retinex 理论很多时候也被称为是视网膜皮层理论。 最初的基于 Retinex 理论的模型提出了一个人眼视觉系统 (…

图像增强算法Retinex原理与实现详解

文章目录 1. 引言2. Retinex算法原理2.1 单尺度Retinex示例代码 2.2 多尺度Retinex示例代码 2.3 颜色恢复示例代码 2.4 最终图像处理代码示例 3. Retinex算法的Python实现4. 完结 1. 引言 图像增强是图像处理中的重要技术之一&#xff0c;它可以改善图像的亮度、对比度和颜色等…

(学习笔记)图像处理——Retinex增强

文章目录 前言原理发展单尺度算法&#xff08;SSR&#xff09;多尺度算法&#xff08;MSR&#xff09;带有色彩恢复的多尺度 实现 前言 Retinex算法由Land于1986年在《An alternative technique for the computation of the designator in the retinex theory of color vision…

Retinex 算法

目录 1、Retinex 理论及数学模型 2、Retinex 算法发展历程 2.1 基于迭代的 Retinex 算法 2.1.1 Frankle-McCann Retinex 算法 2.1.2 McCann99 Retinex 算法 2.2 基于中心环绕的 Retinex 算法 2.2.1 SSR算法&#xff08;单尺度&#xff09; 2.2.2 MSR算法&#xff08;多…

分享一个免费巨好用的shell工具

finalshell 是国产的shell工具&#xff0c;免费&#xff0c;不过可以购买vip&#xff0c;vip功能就是机器进程管理&#xff0c;基本用不上&#xff0c;所以我们只用免费版 功能包含&#xff0c;服务器连接&#xff0c;服务器管理&#xff0c;上传文件&#xff0c;文件可视化操…

shell之常用小工具(sort、uniq、tr、cut)

目录 一、sort 排序 1、格式 2、常用选项 3、sort 例子 1、不加任何选项 如&#xff1a;sort /etc/passwd 2、 去重 &#xff08;sort -u&#xff09; 3、 指定分隔符&#xff08;-t&#xff09;&#xff0c;指定排序的列&#xff08;-k&#xff09;&#xff0c;升序排列…

shell之常用工具的使用

shell入门 文章目录 shell入门一、文本处理工具1. grep工具2. cut工具3. sort工具4.uniq工具5.tee工具6.diff工具7. paste工具8. tr工具二、bash的特性1 、常用的通配符2、bash中的引号&#xff08;重点&#xff09; 一、文本处理工具 1. grep工具 grep是行过滤工具&#xff…

shell工具finalShell

qitashell工具的不足 对于运维人员来说&#xff0c; 使用的最常用的远程终端连接工具无非就是crt或者Xshell, 而crt则需要破解才能使用&#xff0c; Xshell虽说可以免费使用&#xff0c; 但经常在启动的时候会要求你购买&#xff0c; 然后一直卡住不让你启动&#xff0c; 既耽…

shell学习☞shell工具

一、shell工具 1、cut[选项参数] filename&#xff1a;从文件的每一行剪切字解、字符和字段并将这些字节、字符和字段输 选项参数&#xff1a; -f&#xff1a;列号&#xff0c;提取第几列 -d&#xff1a;分隔符&#xff08;默认是制表符&#xff09;&#xff0c;按照指定的分…

惊艳!Linux 中迷人的 Shell 脚本工具

如果您是 Linux 操作系统爱好者或正在将自己定义为一个爱好者&#xff0c;那么与 shell 脚本交叉的路径是完全不可避免的。根据定义&#xff0c;shell 脚本是设计用于在 Unix/Linux shell 环境中执行的程序。 我们可以将命令行解释器 ( shell ) 与诸如打印文本、程序执行和文件…

2.shell工具与脚本

文章目录 一、bash 中的特殊变量二、变量赋值与访问三、其他类型的脚本四、查找文件findlocate 查找内容grep 查找 shell 命令tree broot 五、零碎知识点六、 shell工具 一、bash 中的特殊变量 $0 &#xff1a;脚本名 $1 -$9 :脚本的第1-9个参数 $ :脚本的所有参数 $# :参数个…

Linux---Shell(文本处理工具 和 Shell脚本)

目录 一、文本处理工具 1.1 grep 1.1.1 匹配行首 1.1.2 设置大小写 1.1.3 转义字符 1.2 sed 1.2.1 追加文件 1.2.2 删除文本 1.3 awk 1.3.1 关系表达式 二、Shell脚本 2.1 结构判断 2.2 循环结构 2.3 break 和 continue 2.4 Shell脚本的基本元素与执行方式 一、文…

shell

shell 什么是shell&#xff1a; 现在我们使用的操作系统&#xff08;Windows、Mac OS、Android、iOS等&#xff09;都是带图形界面的&#xff0c;简单直观&#xff0c;容易上手&#xff0c;对专业用户&#xff08;程序员、网管等&#xff09;和普通用户&#xff08;家庭主妇、…