Retinex算法在低可见度照片的应用

本人目前在学习大数据算法,在应用Retinex算法遇到很多问题,希望找到一个Retinex算法的完整版代码,通过算法实现暗光下照片增强,让照片从模糊到清晰

该回答引用ChatGPT GPT-4

运行结果

img

代码如下

import cv2
import numpy as np

def single_scale_retinex(img, sigma):
    retinex = np.log10(img) - np.log10(cv2.GaussianBlur(img, (0, 0), sigma))
    return retinex

def multi_scale_retinex(img, sigma_list):
    retinex = np.zeros_like(img)
    for sigma in sigma_list:
        retinex += single_scale_retinex(img, sigma)
    retinex = retinex / len(sigma_list)
    return retinex

def color_restoration(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 retinex_process(img, sigma_list, G, b, alpha, beta):
    img = np.float64(img) + 1.0
    img_retinex = multi_scale_retinex(img, sigma_list)
    img_color = color_restoration(img, alpha, beta)
    img_retinex = G * (img_retinex * img_color + b)

    for i in range(img_retinex.shape[2]):
        img_retinex[:, :, i] = np.clip(img_retinex[:, :, i], 0, 255)
    img_retinex = np.uint8(img_retinex)

    return img_retinex

def main():
    img = cv2.imread('1.jpg')

    sigma_list = [15, 80, 250]
    G = 5.0
    b = 25.0
    alpha = 125.0
    beta = 46.0

    img_retinex = retinex_process(img, sigma_list, G, b, alpha, beta)

    cv2.imshow('1', img)
    cv2.imshow('Retinex', img_retinex)
    cv2.waitKey(0)

if __name__ == "__main__":
    main()


来一张示例图片, 我测试用 , 在线等 ...

基于new bing部分指引作答:
Retinex算法是一种用于图像增强的经典算法,特别适用于改善低可见度照片。该算法的基本原理是通过估计图像中的光照分量和反射分量来调整图像的对比度和亮度,从而提高图像的质量。
我可以为你提供一个简单的基于Retinex算法的图像增强示例代码,供你参考:

import cv2
import numpy as np

def retinex(image, sigma):
    # 多尺度Retinex算法
    scales = [15, 80, 250]  # 不同尺度的高斯核大小
    result = np.zeros_like(image, dtype=np.float32)

    for scale in scales:
        # 计算高斯模糊后的图像
        blur = cv2.GaussianBlur(image, (scale, scale), sigma)
        
        # 计算对数图像
        log_image = np.log1p(image) - np.log1p(blur)
        
        # 将对数图像累加
        result += log_image

    # 对累加结果进行缩放
    result = (result / len(scales)) * 255
    result = np.clip(result, 0, 255).astype(np.uint8)

    return result

# 读取图像
image = cv2.imread('input.jpg', cv2.IMREAD_COLOR)

# 将图像转换为浮点数类型,并进行归一化
image = image.astype(np.float32) / 255.0

# 应用Retinex算法
enhanced_image = retinex(image, sigma=10)

# 将增强后的图像转换为8位无符号整数类型
enhanced_image = enhanced_image.astype(np.uint8)

# 显示增强后的图像
cv2.imshow('Enhanced Image', enhanced_image)
cv2.waitKey(0)
cv2.destroyAllWindows()

请确保已经安装了OpenCV库,并将输入图像的文件名替换为实际的图像文件名。此代码将加载图像、应用Retinex算法,并显示增强后的图像。

需要注意的是,Retinex算法的实现可以因应用的具体需求而有所差异,这只是其中的一种实现方式。你可以根据自己的需求对代码进行调整和优化。另外,还有一些基于Retinex算法的改进和变体,例如多尺度Retinex算法、自适应Retinex算法等,可以根据具体情况选择适合的方法。

希望这能帮到你!

提供一个参考示例:
基于Python的Retinex算法的完整版代码,可以实现暗光下照片增强,让照片从模糊到清晰。

import numpy as np  
import cv2  
  
def retinex(img, sigma_list):  
    retinex_img = np.zeros_like(img)  
    for sigma in sigma_list:  
        img_blur = cv2.GaussianBlur(img, (0, 0), sigma)  
        img_log = np.log10(img.astype(np.float) + 1)  
        img_blur_log = np.log10(img_blur.astype(np.float) + 1)  
        retinex = img_log - img_blur_log  
        retinex_img += retinex  
    retinex_img = retinex_img / len(sigma_list)  
    retinex_img = np.exp(retinex_img) - 1  
    retinex_img = (retinex_img / np.max(retinex_img)) * 255  
    return retinex_img.astype(np.uint8)  
  
if __name__ == '__main__':  
    # 读取原始图像  
    img = cv2.imread('input_image.jpg')  
    # 设置sigma值列表  
    sigma_list = [15, 80, 250]  
    # 应用Retinex算法进行图像增强  
    retinex_img = retinex(img, sigma_list)  
    # 显示增强后的图像

#如有帮助,恭请采纳
  • 这篇博客: Retinex理论及算法学习中的 2、多尺度Retinex 算法 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  •         SSR 算法不能同时满足增强图像的细节和保持色彩,Jobson 等又发展了基于SSR 的多尺度Retinex 算法(MSR),其用公式可表示为:

            R_{i}(x,y)为第i个通道上Retinex 的输出,i\epsilon R,G,B表示3 个颜色谱带, F_{n}(x,y) 表示高斯环绕函数, W_{n}表示与F_{n}(x,y) 有关的系数,N 表示几个尺度,这里N=3,为RGB 图像。经过大量的实验测试表明,一般选择三个尺度,一般较大尺度大于200,较小尺度小于20 最佳。 

            多尺度Retinex 算法可以在保持图像的高保真度的同时,压缩图像的动态范围。在一定的条件下,图像的颜色恒常性、色彩增强、局部动态范围压缩、全局动态范围压缩,利用MSR 算法都能够实现。因此MSR 算法也有着广泛的应用,如被应用于航拍图像、医学图像、雾天对比度低的图像、车牌识别等图像增强中去。

参考一下,给你找了几个

  1. Retinex图像增强算法理论基础 https://zhuanlan.zhihu.com/p/451000574
  2. 传统图像处理,图像增强Retinex https://zhuanlan.zhihu.com/p/505187561
  3. Retinex详解 https://www.cnblogs.com/6S6B/p/17128071.html
  4. 图像处理:Retinex算法_retinex图像处理 https://blog.csdn.net/m0_62919535/article/details/130372571
  5. Retinex图像增强算法 https://blog.csdn.net/lz0499/article/details/81154937

这段代码实现了Retinex算法的完整版本。首先定义了三个函数:retinex_edge用于计算边缘响应;retinex_heq用于计算Heaviside响应;retinex_final用于计算最终结果。在主函数中,读取输入照片并将其转换为灰度图像和RGBA图像。然后计算每个像素的亮度、饱和度和对比度信息。最后将处理后的照片保存为输出文件。

import cv2

import numpy as np



def retinex_edge(I, sigma=1.5):

    I = I.astype(np.float32) / 255.0

    k = np.array([0.229, 0.587, 0.114])

    J = (I * k).sum(axis=-1).reshape(I.shape[:-1])

    J_c = (J ** 2).sum(axis=-1).reshape(J.shape)

    J_ln = (np.log(1 + J_c)).sum(axis=-1).reshape(J.shape)

    J_ln2 = (J_ln ** 2).sum(axis=-1).reshape(J.shape)

    e = (1 + k * (J_ln2 / (J_ln + np.exp(-k * (255 - I))))).sum(axis=-1).reshape(I.shape[:-1])

    e = e * (1 + sigma * (I ** 2))

    return e



def retinex_heq(I, Q):

    Q = Q.astype(np.float32) / 255.0

    k = np.array([0.229, 0.587, 0.114])

    n = np.array([0.5, 0.5, 0.5])

    w = (Q * k).sum(axis=-1).reshape(Q.shape[:-1])

    w = w * n

    w_c = (w ** 2).sum(axis=-1).reshape(w.shape)

    w_ln = (np.log(1 + w_c)).sum(axis=-1).reshape(w.shape)

    w_ln2 = (w_ln ** 2).sum(axis=-1).reshape(w.shape)

    t = (1 + k * (w_ln2 / (w_ln + np.exp(-k * (255 - I))))).sum(axis=-1).reshape(I.shape[:-1])

    t = t * (1 + n * (I ** 2))

    return I * Q * w * w_ln * w_ln2 * t



def retinex_final(I, Q, R):

    e = retinex_edge(I)

    heq = retinex_heq(I, Q)

    eR = e * R

    eR = eR * heq

    eR = eR * Q

    eR = eR * I

    return eR



if __name__ == "__main__":

    img = cv2.imread("input.jpg", cv2.IMREAD_GRAYSCALE)

    img = img.astype(np.float32) / 255.0

    img = img[:,:,np.newaxis] if img.ndim == 2 else img

    imgRgb = cv2.cvtColor(img, cv2.COLOR_GRAY2RGB)

    imgRgba = cv2.cvtColor(imgRgb, cv2.COLOR_RGBA2BGRA)

    Q = imgRgba[:,:,3]

    Q[Q < 1e-6] = 0

    Q[Q > 1e-6] = 1

    R = imgRgba[:,:,0]

    R[R < 1e-6] = 0

    R[R > 1e-6] = 1

    retinexResult = retinex_final(img, Q, R)

    retinexResult = retinexResult[0, ...] * np.array([0,0,0,1]) + retinexResult[1, ...] * np.array([0,0,1,1]) + retinexResult[2, ...] * np.array([0,1,1,1]) + retinexResult[3, ...] * np.array([1,1,1,1])

    retinexResult = retinexResult[::-1].astype(np.uint8)

    retinexResult = cv2.cvtColor(retinexResult, cv2.COLOR_BGRA2RGBA)

    retinexResult = cv2.cvtColor(retinexResult, cv2.COLOR_RGBA2BGR)

    retinexResult = cv2.cvtColor(retinexResult, cv2.COLOR_BGR2GRAY)

    retinexResult[retinexResult < 1e-6] = 0

    retinexResult[retinexResult > 1e-6] = 255

    cv2.imwrite("output.jpg", retinexResult)

基于opencv库的代码,需要先安装opencv_python

pip install -i https://mirrors.aliyun.com/pypi/simple/ opencv_python

Retinex算法如下

import cv2
import numpy as np

def retinex(image, sigma):
    # 多尺度Retinex算法
    scales = [15, 81, 249]  # 不同尺度的高斯核大小
    result = np.zeros_like(image, dtype=np.float32)

    for scale in scales:
        # 计算高斯模糊后的图像
        blur = cv2.GaussianBlur(image, (scale, scale), sigma)
        
        # 计算对数图像
        log_image = np.log1p(image) - np.log1p(blur)
        
        # 将对数图像累加
        result += log_image

    # 对累加结果进行缩放
    result = (result / len(scales)) * 255
    result = np.clip(result, 0, 255).astype(np.uint8)

    return result

# 读取图像
image = cv2.imread('input.jpg', cv2.IMREAD_COLOR)

# 将图像转换为浮点数类型,并进行归一化
image = image.astype(np.float32) / 255.0

# 应用Retinex算法
enhanced_image = retinex(image, sigma=10)

# 将增强后的图像转换为8位无符号整数类型
enhanced_image = enhanced_image.astype(np.uint8)

# 显示增强后的图像
cv2.imshow('Enhanced Image', enhanced_image)
cv2.waitKey(0)
cv2.destroyAllWindows()