Retinex视网膜算法(SSR、MSR、MSRCR)
Retinex视网膜算法
Retinex算法模拟人类视觉系统对光照和反射的处理机制,核心是将图像分解为光照分量(Luminance)和反射分量(Reflectance),公式为:
I(x,y)=R(x,y)×L(x,y) I(x,y) = R(x,y) \times L(x,y) I(x,y)=R(x,y)×L(x,y)
通过对数变换转为加法模型(便于分离分量):
log(I(x,y))=log(R(x,y))+log(L(x,y)) \log(I(x,y)) = \log(R(x,y)) + \log(L(x,y)) log(I(x,y))=log(R(x,y))+log(L(x,y))
以下是 SSR、MSR、MSRCR 的原理与区别:
1. 单尺度 Retinex(SSR, Single - Scale Retinex)
核心思想:用单个高斯核估计光照分量,分离反射分量实现增强。
步骤:
-
对数变换:将图像转对数空间,拆分光照和反射的加法关系:
log(I)=log(R)+log(L) \log(I) = \log(R) + \log(L) log(I)=log(R)+log(L) -
高斯滤波估计光照:
用高斯核 ( G_{\sigma} ) 对对数图像卷积,模拟缓慢变化的光照:
log(L)≈Gσ∗log(I) \log(L) \approx G_{\sigma} * \log(I) log(L)≈Gσ∗log(I)
(( * ) 表示卷积,( \sigma ) 是高斯核标准差,控制光照平滑程度) -
提取反射分量:
反射分量的对数为原始对数图像减去光照对数:
log(R)=log(I)−log(L) \log(R) = \log(I) - \log(L) log(R)=log(I)−log(L) -
指数变换还原:
将反射分量转回线性空间:
R=exp(log(R)) R = \exp(\log(R)) R=exp(log(R)) -
归一化:映射到 0 - 255 范围,输出增强图像。
特点:
- 优点:计算简单,适合增强局部细节。
- 缺点:仅用一个尺度,易出现过度增强(小 ( \sigma ))或细节丢失(大 ( \sigma )),对不同场景适应性弱。
代码实现
import cv2
import numpy as np
import matplotlib.pyplot as pltdef single_scale_retinex(img, sigma=128, normalize=True):"""SSR算法实现:param img: 输入图像 (BGR格式):param sigma: 高斯核标准差 (控制光照估计尺度):param normalize: 是否进行结果归一化:return: 增强后的图像"""# 转换为浮点型并加1避免log(0)img = img.astype(np.float32) / 255.0 + 1e-6# 分别处理每个通道channels = []for ch in range(3):img_ch = img[:, :, ch]# 步骤1: 高斯模糊估计光照分量gaussian = cv2.GaussianBlur(src=img_ch,ksize=(0, 0), # 自动根据sigma计算核大小sigmaX=sigma,sigmaY=sigma)# 步骤2: 对数域减法分离反射分量log_img = np.log(img_ch)log_blur = np.log(gaussian)retinex = log_img - log_blurchannels.append(retinex)# 合并通道result = np.stack(channels, axis=2)# 可选归一化 (增强视觉效果)if normalize:result = (result - np.min(result)) / (np.max(result) - np.min(result))result = (result * 255).astype(np.uint8)return result# 示例使用
if __name__ == "__main__":# 读取图像image = cv2.imread('img_1.png') # 替换为你的图像路径# 应用SSRssr_result = single_scale_retinex(image, sigma=100,normalize=True)cv2.imwrite('enhanced_image.png', ssr_result)# 显示结果plt.figure(figsize=(12, 6))plt.subplot(121)plt.title("Original Image")plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))plt.axis('off')plt.subplot(122)plt.title("SSR Enhanced")plt.imshow(cv2.cvtColor(ssr_result, cv2.COLOR_BGR2RGB))plt.axis('off')plt.tight_layout()plt.savefig('ssr_result.jpg', dpi=300)plt.show()
结果图像
输入图像:
增强图像:
2. 多尺度 Retinex(MSR, Multi - Scale Retinex)
核心思想:融合多个不同尺度的 SSR 结果,平衡全局与局部增强。
步骤:
-
多尺度 SSR 计算:
用一组不同 sigmasigmasigma 的高斯核(如sigma1sigma1sigma1,sigma2sigma2sigma2,sigma3sigma3sigma3),分别计算单尺度 Retinex:
MSR=1N∑i=1N[log(I)−log(Gσi∗I)] MSR = \frac{1}{N} \sum_{i=1}^N \left[ \log(I) - \log\left(G_{\sigma_i} * I\right) \right] MSR=N1i=1∑N[log(I)−log(Gσi∗I)]
(( N ) 是尺度数量,通常取 3 - 5 个尺度覆盖不同频率) -
直接输出或后处理:
多尺度结果已平衡全局光照和局部细节,可直接归一化输出。
特点:
- 优点:比 SSR 更鲁棒,兼顾大尺度(保留整体对比度)和小尺度(增强细节)。
- 缺点:未显式处理颜色失真,易出现色偏;仅优化对比度,未针对性恢复颜色。
代码实现
import cv2
import numpy as np
import matplotlib.pyplot as pltdef multi_scale_retinex(img, sigma_list=[15, 80, 250], weights=None, normalize=True):"""MSR算法实现:param img: 输入图像 (BGR格式):param sigma_list: 高斯核标准差列表,定义不同尺度:param weights: 各尺度的权重,默认等权重:param normalize: 是否进行结果归一化:return: 增强后的图像"""# 如果没有提供权重,则使用等权重if weights is None:weights = [1.0 / len(sigma_list)] * len(sigma_list)elif len(weights) != len(sigma_list):raise ValueError("权重列表长度必须与sigma_list相同")# 转换为浮点型并加1避免log(0)img = img.astype(np.float32) / 255.0 + 1e-6# 初始化MSR结果msr = np.zeros_like(img)# 对每个尺度进行处理for sigma, weight in zip(sigma_list, weights):# 分别处理每个通道channels = []for ch in range(3):img_ch = img[:, :, ch]# 高斯模糊估计光照分量gaussian = cv2.GaussianBlur(src=img_ch,ksize=(0, 0),sigmaX=sigma,sigmaY=sigma)# 对数域减法分离反射分量retinex = np.log(img_ch) - np.log(gaussian)channels.append(retinex)# 加权累加到MSR结果msr += weight * np.stack(channels, axis=2)# 可选归一化 (增强视觉效果)if normalize:# 将结果缩放到0~255msr = (msr - np.min(msr)) / (np.max(msr) - np.min(msr))msr = (msr * 255).astype(np.uint8)return msr# 示例使用
if __name__ == "__main__":# 读取图像image = cv2.imread('img_1.png') # 替换为你的图像路径# 应用MSR (三个尺度)msr_result = multi_scale_retinex(image,sigma_list=[15, 80, 250], # 小、中、大三个尺度weights=[0.4, 0.3, 0.3], # 权重分配normalize=True)# 保存结果cv2.imwrite('msr_enhanced.png', msr_result)# 与单尺度结果对比ssr_small = multi_scale_retinex(image, sigma_list=[15])ssr_medium = multi_scale_retinex(image, sigma_list=[80])ssr_large = multi_scale_retinex(image, sigma_list=[250])# 对比显示plt.figure(figsize=(18, 10))plt.subplot(231)plt.title("Original Image")plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))plt.axis('off')plt.subplot(232)plt.title("SSR (Small Scale, σ=15)")plt.imshow(cv2.cvtColor(ssr_small, cv2.COLOR_BGR2RGB))plt.axis('off')plt.subplot(233)plt.title("SSR (Medium Scale, σ=80)")plt.imshow(cv2.cvtColor(ssr_medium, cv2.COLOR_BGR2RGB))plt.axis('off')plt.subplot(234)plt.title("SSR (Large Scale, σ=250)")plt.imshow(cv2.cvtColor(ssr_large, cv2.COLOR_BGR2RGB))plt.axis('off')plt.subplot(235)plt.title("MSR (Multi-Scale)")plt.imshow(cv2.cvtColor(msr_result, cv2.COLOR_BGR2RGB))plt.axis('off')plt.tight_layout()plt.savefig('msr_comparison.jpg', dpi=300, bbox_inches='tight')plt.show()
结果图像
输入图像:
增强图像:
3. 多尺度 Retinex 颜色恢复(MSRCR, Multi - Scale Retinex with Color Restoration)
核心思想:在 MSR 基础上,增加**颜色恢复(Color Restoration)**步骤,解决色偏问题。
步骤:
-
多尺度 Retinex(MSR):
同 MSR 步骤,得到反射分量的对数 ( \log® )。 -
颜色恢复(Color Restoration):
用原始图像的颜色统计信息,补偿反射分量的色偏。公式(以 RGB 通道为例):
CRc=β⋅[log(α⋅Ic)−log(∑c=R,G,BIc)] CR_c = \beta \cdot \left[ \log(\alpha \cdot I_c) - \log\left( \sum_{c=R,G,B} I_c \right) \right] CRc=β⋅log(α⋅Ic)−logc=R,G,B∑Ic- ( CR_c ):通道 ( c ) 的颜色恢复因子
- ( \alpha, \beta ):调整参数(控制颜色恢复强度,需经验调参)
- 作用:让颜色更贴近原始图像的色彩分布,避免 MSR 导致的色偏。
-
融合反射与颜色恢复:
最终增强公式:
MSRCR=G⋅(R⋅CR+b) MSRCR = G \cdot \left( R \cdot CR + b \right) MSRCR=G⋅(R⋅CR+b)- ( G ):增益系数(调整整体亮度)
- ( b ):偏移量(微调亮度基准)
-
颜色平衡(可选):
对每个通道做直方图截断(如simplestColorBalance
),限制极端亮度值,优化颜色分布。
特点:
- 优点:在 MSR 基础上解决色偏,增强后颜色更自然;适合低光、雾天等场景的图像增强。
- 缺点:参数多(( \sigma ) 组、( \alpha, \beta, G, b ) 等),需经验调参;计算复杂度高于 SSR/MSR。
代码实现
import numpy as np
import cv2
import matplotlib.pyplot as plt# 单尺度 Retinex 计算
def singleScaleRetinex(img, sigma):temp = cv2.GaussianBlur(img, (0, 0), sigma)gaussian = np.where(temp == 0, 0.01, temp)retinex = np.log10(img + 0.01) - np.log10(gaussian)return retinex# 多尺度 Retinex 计算
def multiScaleRetinex(img, sigma_list):retinex = np.zeros_like(img, dtype=np.float64)for sigma in sigma_list:retinex += singleScaleRetinex(img, sigma)retinex = retinex / len(sigma_list)return retinex# 颜色恢复
def colorRestoration(img, alpha, beta):img_sum = np.sum(img, axis=2, keepdims=True)color_restoration = beta * (np.log10(alpha * img) - np.log10(img_sum))return color_restoration# 简单颜色平衡
def simplestColorBalance(img, low_clip, high_clip):total = img.shape[0] * img.shape[1]for i in range(img.shape[2]):current = img[:, :, i]unique, counts = np.unique(current, return_counts=True)low_val = 0high_val = 0cumulative_count = 0for u, c in zip(unique, counts):if float(cumulative_count) / total < low_clip:low_val = ucumulative_count += celif float(cumulative_count) / total < high_clip:high_val = ucumulative_count += celse:if high_val == 0:high_val = ubreakcurrent = np.maximum(np.minimum(current, high_val), low_val)img[:, :, i] = currentreturn img# MSRCR 算法实现
def MSRCR(img, sigma_list, G, b, alpha, beta, low_clip, high_clip):img = np.float64(img) + 1.0img_retinex = multiScaleRetinex(img, sigma_list)img_color = colorRestoration(img, alpha, beta)img_msrcr = G * (img_retinex * img_color + b)for i in range(img_msrcr.shape[2]):img_msrcr[:, :, i] = (img_msrcr[:, :, i] - np.min(img_msrcr[:, :, i])) / \(np.max(img_msrcr[:, :, i]) - np.min(img_msrcr[:, :, i])) * 255img_msrcr = np.uint8(np.minimum(np.maximum(img_msrcr, 0), 255))img_msrcr = simplestColorBalance(img_msrcr, low_clip, high_clip)return img_msrcrif __name__ == "__main__":# 读取图像image_path = r'E:\lgl\DeepLearning\retinex\img_1.png' # 替换为你的图像路径img = cv2.imread(image_path)if img is None:print("无法读取图像,请检查路径是否正确。")else:# 设置参数sigma_list = [15, 80, 250] # 多尺度的 sigma 值G = 5 # 增益系数b = 20 # 偏移量alpha = 125 # 颜色恢复参数 alphabeta = 46 # 颜色恢复参数 betalow_clip = 0.01 # 颜色平衡低阈值high_clip = 0.99 # 颜色平衡高阈值# 应用 MSRCR 算法result = MSRCR(img, sigma_list, G, b, alpha, beta, low_clip, high_clip)cv2.imwrite('enhanced_image.png', result)# 显示原始图像和处理后的图像(需要导入 matplotlib 库)plt.subplot(121)plt.title("Original Image")plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))plt.axis('off')plt.subplot(122)plt.title("MSRCR Enhanced")plt.imshow(cv2.cvtColor(result, cv2.COLOR_BGR2RGB))plt.axis('off')plt.tight_layout()plt.savefig('msrcr_result.jpg', dpi=300)plt.show()
结果图像
输入图像:
增强图像:
三类算法对比
算法 | 核心优势 | 典型应用场景 | 不足 |
---|---|---|---|
SSR | 计算简单,局部细节增强效果明显 | 小范围细节优化(如医学图像) | 尺度单一,适应性差 |
MSR | 多尺度平衡,兼顾全局与局部增强 | 通用图像增强(如监控、遥感) | 易色偏,无颜色恢复机制 |
MSRCR | 多尺度 + 颜色恢复,自然还原色彩 | 低光、雾天图像(如夜景、航拍) | 参数多,计算复杂度高 |
总结
Retinex 系列算法的本质是分离光照和反射,通过增强反射分量(细节)提升图像质量:
- SSR 是基础,适合简单场景;
- MSR 用多尺度弥补 SSR 的局限性;
- MSRCR 进一步加入颜色恢复,解决色偏问题,是更实用的工程方案(如低光图像增强、去雾等任务)。
实际使用中,MSRCR 因颜色自然更常用,但需注意参数调优(尤其是 ( \sigma ) 组和颜色恢复参数);若追求极致效率,SSR 或 MSR 也可根据场景适配。