Retinex算法在暗光增强应用以及Python实现

本文深入探讨Retinex理论及其在图像增强中的应用,包括单尺度Retinex(SSR)、多尺度Retinex(MSR)及带色彩恢复的多尺度Retinex(MSRCR)等算法。解析Retinex如何实现颜色恒常性,动态范围压缩及边缘增强,提供Python实现代码。

Retinex简介

Retinex由两个单词合成的一个词语,他们分别是retina 和cortex,即:视网膜和皮层。Land的retinex模式是建立在以下三个假设之上的:

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

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

根据另一篇博客讲,Retinex核心包括两方面:

(1)在颜色感知时,人眼对局部相对光强敏感程度要优于绝对光强。
(2)反射分量R(x,y)储存有无光源物体的真实模样,一幅图像对其光照分量L(x,y)的估计越准确,求得的R(x,y)也就越准确。

对于第一点,人对颜色的认知并不是基于绝对光强,反应在图像上时可以理解成,人眼对一像素点(X0,Y0)的颜色的认知不是基于其RGB三通道绝对值大小,而是与俩个因素相关:

1、(X0,Y0)点三通道值的差异,它会致使色偏。
2、(X0,Y0)一个邻域内其余像素的RGB值,它会形成颜色的感觉,RGB三通道绝对值主导亮度感觉。

对于第二点,在给定场景的时候,如果场景内无光源,那么R(x,y)应该是一常量。无论光照L(x,y)如何改变,R(x,y)该不变。也就是说,无论我光照是什么颜色什么强度,我都应该能将其矫正到标准光照情况下。这也是色彩恒常性的体现。

Single Scale Retinex(SSR)

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

def single_scale_retinex(img, sigma):
    """Single Scale Retinex
    Arguments:
        img {np.ndarray} -- process image
        sigma {int} -- [description]
    Returns:
        retinex {np.ndarray} -- float64, needs to rescale to 0~255
    """
    retinex = np.log10(img) - np.log10(cv2.GaussianBlur(img, (0, 0), sigma))
    return retinex

第二种算法的实现,这种好像更清晰理解:

#SSR
def replaceZeroes(data):
    min_nonzero = min(data[nonzero(data)])
    data[data == 0] = min_nonzero
    return data
 
def 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)#将像素点进行绝对值计算, src表示当前图片
 
    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表示在对数域的图像的输出。
python实现:

def multi_scale_retinex(img, sigma_list):
    """Multi Scale Retinex
    Arguments:
        img {np.ndarray} -- process image
        sigma_list {list of int} -- list of sigma for SSR
    Returns:
        retinex {np.ndarray} -- float64, needs to rescale to 0~255
    """
    retinex = np.zeros_like
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值