文章简介

本文聚焦低照度图像增强领域,深入解析Retinex理论及其三大经典变种——单尺度SSR多尺度MSR色彩恢复MSRCR的算法原理,并提供完整Python实现代码。通过拆解图像「照度分量」与「反射分量」的分离逻辑,结合高斯滤波、对数变换等操作,帮助读者理解如何平衡动态范围压缩边缘增强颜色恒常性,最终实现低照度图像的有效增强。

一、Retinex理论基础

Retinex(Retina-Cortex,视网膜-皮层)算法由Edwin H. Land于1963年提出,其核心灵感来源于人类视觉系统的色彩恒常性——人眼能在不同光照条件下感知物体的固有颜色(如白墙在阳光下和阴影里都被感知为白色)。

1.1 图像分解模型

Retinex理论认为,原始图像可分解为「照度分量」与「反射分量」的乘积
I(x,y)=R(x,y)⋅L(x,y) I(x,y) = R(x,y) \cdot L(x,y) I(x,y)=R(x,y)L(x,y)

  • (I(x,y)):相机捕获的原始低照度图像;
  • (L(x,y)):照度分量(环境光照射,反映光线的明暗变化,通常是缓慢平滑的);
  • (R(x,y)):反射分量(物体的固有属性,包含细节与真实颜色,是我们需要保留的目标)。

1.2 对数域转换

由于人类对亮度的感知更接近对数特性(强光下亮度变化的感知敏感度降低),将公式转换到对数域(把乘法转为加法,简化计算):
i(x,y)=r(x,y)+l(x,y) i(x,y) = r(x,y) + l(x,y) i(x,y)=r(x,y)+l(x,y)
其中:

  • (i = \log(I))、(r = \log®)、(l = \log(L));
  • 目标:从(I)中估计(L),并分离出(R)(即增强后的图像)。

二、Retinex核心算法

Retinex的本质是通过滤波估计照度分量(L),再通过对数减法分离反射分量(R)。根据滤波尺度的不同,衍生出三大经典算法:

2.1 单尺度Retinex(SSR):基础款

2.1.1 算法原理

SSR(Single Scale Retinex)是Retinex的基础实现,核心逻辑是:

  1. 单尺度高斯滤波估计照度分量(L)(高斯核越大,滤波越平滑,对应照度的慢变化);
  2. 通过对数减法分离反射分量(R);
  3. 将结果量化到0-255范围。

关键公式:

  • 高斯核定义(尺度由(\sigma)控制,(\sigma)越大,滤波越平滑):
    Gσ(x,y)=12πσ2e−x2+y22σ2 G_\sigma(x,y) = \frac{1}{2\pi\sigma^2} e^{-\frac{x^2 + y^2}{2\sigma^2}} Gσ(x,y)=2πσ21e2σ2x2+y2
  • 照度分量估计(高斯滤波):
    L(x,y)=I(x,y)∗Gσ(x,y) L(x,y) = I(x,y) * G_\sigma(x,y) L(x,y)=I(x,y)Gσ(x,y)
    ((*)表示卷积操作)
  • 反射分量分离(对数域):
    r(x,y)=log⁡(I(x,y))−log⁡(L(x,y)) r(x,y) = \log(I(x,y)) - \log(L(x,y)) r(x,y)=log(I(x,y))log(L(x,y))
  • 结果量化(映射到0-255):
    R(x,y)=normalize(r(x,y),0,255) R(x,y) = \text{normalize}(r(x,y), 0, 255) R(x,y)=normalize(r(x,y),0,255)
2.1.2 Python实现
import cv2
import numpy as np

## SSR
def SSR(img, sigma):
    img_log = np.log1p(np.array(img, dtype="float") / 255)
    img_fft = np.fft.fft2(img_log)
    G_recs = sigma // 2 + 1
    result = np.zeros_like(img_fft)
    rows, cols, deep = img_fft.shape
    for z in range(deep):
        for i in range(rows):
            for j in range(cols):
                for k in range(1, G_recs):
                    G = np.exp(-((np.log(k) - np.log(sigma)) ** 2) / (2 * np.log(2) ** 2))
                    result[i, j] += G * img_fft[i, j]
    img_ssr = np.real(np.fft.ifft2(result))
    img_ssr = np.exp(img_ssr) - 1
    img_ssr = np.uint8(cv2.normalize(img_ssr, None, 0, 255, cv2.NORM_MINMAX))
    return img_ssr

# 测试代码
if __name__ == "__main__":
    input_img = cv2.imread("image/low.png")
    gt_img = cv2.imread("image/high.png")

    enhanced_img = SSR(input_img, 7)

    cv2.imshow("Input", input_img)
    cv2.imshow("SSR Enhanced", enhanced_img)
    cv2.imshow("GT high", gt_img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

2.2 多尺度Retinex(MSR):平衡款

为解决SSR的尺度依赖问题,MSR(Multi-Scale Retinex)通过多尺度高斯核融合,平衡细节保留与噪声抑制。

2.2.1 算法原理

MSR的核心逻辑是:

  1. 3个不同尺度的高斯核(小、中、大)分别计算SSR;
  2. 对3个结果均等加权融合(各占1/3);
  3. 量化到0-255范围。

关键公式((N=3)为尺度数量):
rMSR=13∑i=13[log⁡(I)−log⁡(I∗Gσi)] r_{\text{MSR}} = \frac{1}{3} \sum_{i=1}^3 \left[ \log(I) - \log(I * G_{\sigma_i}) \right] rMSR=31i=13[log(I)log(IGσi)]
其中(\sigma_1 < \sigma_2 < \sigma_3)(如([15, 101, 301])),分别对应细节、纹理、全局亮度

2.2.2 Python实现
import numpy as np
import cv2

## MSR
def MSR(img, scales):
    img_log = np.log1p(np.array(img, dtype="float") / 255)
    result = np.zeros_like(img_log)
    img_light = np.zeros_like(img_log)
    r, c, deep = img_log.shape
    for z in range(deep):
        for scale in scales:
            kernel_size = scale * 4 + 1
            # 高斯滤波器的大小,经验公式kernel_size = scale * 4 + 1
            sigma = scale
            img_smooth = cv2.GaussianBlur(img_log[:, :, z], (kernel_size, kernel_size), sigma)
            img_detail = img_log[:, :, z] - img_smooth
            result[:, :, z] += cv2.resize(img_detail, (c, r))
            img_light[:, :, z] += cv2.resize(img_smooth, (c, r))
    img_msr = np.exp(result+img_light) - 1
    img_msr = np.uint8(cv2.normalize(img_msr, None, 0, 255, cv2.NORM_MINMAX))
    return img_msr


if __name__=="__main__":
    input_img = cv2.imread("image/low.png")
    gt_img = cv2.imread("image/high.png")

    enhanced_img = MSR(input_img, [80, 200])

    cv2.imshow("Input", input_img)
    cv2.imshow("MSR Enhanced", enhanced_img)
    cv2.imshow("GT high", gt_img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

2.3 色彩恢复Retinex(MSRCR):终极款

为解决MSR的色彩失真问题,MSRCR(Multi-Scale Retinex with Color Restoration)在MSR基础上加入色彩恢复因子,通过「色比」(单通道与全通道之和的比值)保留颜色恒常性。

2.3.1 算法原理

MSRCR的核心改进是:

  1. 计算MSR的反射分量(r_{\text{MSR}});
  2. 乘以色彩恢复因子(C(x,y))(用色比修正颜色);
  3. 通过简单颜色平衡(Simple Color Balance)拉伸对比度。

关键公式:

  • 色彩恢复因子((\alpha=125)、(\beta=46)为经验值):
    C(x,y)=β⋅log⁡(α⋅I(x,y)∑c=13Ic(x,y)) C(x,y) = \beta \cdot \log\left( \alpha \cdot \frac{I(x,y)}{\sum_{c=1}^3 I_c(x,y)} \right) C(x,y)=βlog(αc=13Ic(x,y)I(x,y))
    其中(\sum_{c=1}^3 I_c(x,y))是RGB三通道之和(全通道亮度),(\frac{I}{\sum I})是色比(保留颜色恒常性)。
  • MSRCR最终结果:
    rMSRCR=rMSR⋅C(x,y) r_{\text{MSRCR}} = r_{\text{MSR}} \cdot C(x,y) rMSRCR=rMSRC(x,y)
  • 简单颜色平衡(拉伸直方图两端的2%和3%像素,增强对比度):
    Rfinal=balance(rMSRCR,s1=0.02,s2=0.03) R_{\text{final}} = \text{balance}(r_{\text{MSRCR}}, s1=0.02, s2=0.03) Rfinal=balance(rMSRCR,s1=0.02,s2=0.03)
2.3.2 Python实现
import numpy as np
import cv2

## MSRCR
def MSRCR(img, scales, k):
    img_log = np.log1p(np.array(img, dtype="float") / 255)
    result = np.zeros_like(img_log)
    img_light = np.zeros_like(img_log)
    r, c, deep = img_log.shape
    for z in range(deep):
        for scale in scales:
            kernel_size = scale * 4 + 1
            # 高斯滤波器的大小,经验公式kernel_size = scale * 4 + 1
            sigma = scale
            G_ratio = sigma ** 2 / (sigma ** 2 + k)
            img_smooth = cv2.GaussianBlur(img_log[:, :, z], (kernel_size, kernel_size), sigma)
            img_detail = img_log[:, :, z] - img_smooth
            result[:, :, z] += cv2.resize(img_detail, (c, r))
            result[:, :, z] = result[:, :, z] * G_ratio
            img_light[:, :, z] += cv2.resize(img_smooth, (c, r))

    img_msrcr = np.exp(result + img_light) - 1
    img_msrcr = np.uint8(cv2.normalize(img_msrcr, None, 0, 255, cv2.NORM_MINMAX))
    return img_msrcr

if __name__=="__main__":
    input_img = cv2.imread("image/low.png")
    gt_img = cv2.imread("image/high.png")

    enhanced_img = MSRCR(input_img,[15, 80, 200],12)

    cv2.imshow("Input", input_img)
    cv2.imshow("MSR Enhanced", enhanced_img)
    cv2.imshow("GT high", gt_img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

在这里插入图片描述

三、算法总结与对比

算法 核心改进 优点 缺点 适用场景
SSR 单尺度高斯滤波 计算快 尺度依赖,易噪声/丢细节 简单低照度场景
MSR 多尺度融合 平衡细节与平滑 易偏色 需要保留纹理的场景
MSRCR 色彩恢复+颜色平衡 颜色自然,细节丰富 计算复杂 要求颜色恒常的场景(如监控、遥感)

获取更多资料

我给大家整理了一套全网最全的人工智能学习资料(1.5T),包括:机器学习,深度学习,大模型,CV方向,NLP方向,kaggle大赛,实战项目、自动驾驶,AI就业等免费获取
请添加图片描述
请添加图片描述

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐