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

1. 引言

图像增强是图像处理中的重要技术之一,它可以改善图像的亮度、对比度和颜色等视觉效果,使图像更加清晰、鲜明。Retinex是一种经典的图像增强算法,它通过对图像进行多尺度高斯模糊处理和颜色恢复操作来改善图像的视觉效果。本文将详细介绍Retinex算法的原理,并给出了Python实现的示例代码和测试结果。
在这里插入图片描述

2. Retinex算法原理

 Retinex算法原理

Retinex算法是基于人眼视觉系统特性的图像增强算法,它通过对图像进行多尺度的处理来提高图像的亮度和颜色表现。

2.1 单尺度Retinex

在这里插入图片描述

单尺度Retinex算法是Retinex算法的基本操作,它通过对图像进行高斯模糊处理和对数运算来得到增强后的图像。具体步骤如下:

  1. 对输入图像进行高斯模糊处理,使用cv2.GaussianBlur()函数实现,其中参数sigma表示高斯核的标准差。
  2. 对模糊后的图像和原图像分别进行对数运算,得到两个对数图像。
  3. 将两个对数图像相减,得到增强后的图像。

示例代码

import cv2  # 导入OpenCV库,用于图像处理
import numpy as np  # 导入NumPy库,用于科学计算和数组操作

def single_scale_retinex(img, sigma):
    retinex = np.log10(img) - np.log10(cv2.GaussianBlur(img, (0, 0), sigma))
    # 计算图像的单尺度Retinex算法
    # np.log10(img) 对输入图像img进行log10变换,将像素值转换为对数域
    # cv2.GaussianBlur(img, (0, 0), sigma) 对输入图像img进行高斯模糊处理,sigma为高斯核的标准差
    # np.log10(...) - np.log10(...) 执行两个结果之间的减法运算,得到Retinex结果
    return retinex

解释说明
这段代码实现了基于单尺度Retinex算法的图像增强

  • import cv2:导入OpenCV库,用于图像处理。

  • import numpy as np:导入NumPy库,用于科学计算和数组操作。

  • def single_scale_retinex(img, sigma)::定义了一个函数single_scale_retinex,接收两个参数imgsigma,分别代表输入的图像和高斯核的标准差。

    扫描二维码关注公众号,回复: 15949395 查看本文章
  • retinex = np.log10(img) - np.log10(cv2.GaussianBlur(img, (0, 0), sigma)):计算图像的单尺度Retinex算法。

    • np.log10(img)对输入图像img进行log10变换,将像素值转换为对数域。
    • cv2.GaussianBlur(img, (0, 0), sigma)对输入图像img进行高斯模糊处理,使用高斯核进行图像平滑,其中(0, 0)表示核的大小为自动计算。
    • np.log10(...) - np.log10(...)执行两个结果之间的减法运算,得到Retinex结果。
  • return retinex:返回计算得到的Retinex结果。

2.2 多尺度Retinex

多尺度Retinex

多尺度Retinex是在单尺度Retinex的基础上进一步改进的算法,它通过对不同尺度下的图像进行单尺度Retinex增强,并将结果累加求平均得到最终的增强图像。具体步骤如下:

  1. 定义一个尺度列表sigma_list,包含不同的标准差值。
  2. 循环遍历尺度列表中的每个标准差sigma,调用单尺度Retinex算法对图像进行增强,并将结果逐步累加。
  3. 将累加后的图像除以尺度列表的长度,得到最终的增强图像。

示例代码

def multi_scale_retinex(img, sigma_list):
    retinex = np.zeros_like(img)  # 创建与输入图像相同大小的全零数组,用于存储Retinex结果
    for sigma in sigma_list:
        retinex += single_scale_retinex(img, sigma)
        # 调用single_scale_retinex函数计算单尺度Retinex,并将结果累加到retinex数组中
    retinex = retinex / len(sigma_list)
    # 将累加的Retinex结果除以sigma_list的长度,得到平均Retinex结果
    return retinex

解释说明
这段代码实现了基于多尺度Retinex算法的图像增强。

  • def multi_scale_retinex(img, sigma_list)::定义了一个函数multi_scale_retinex,接收两个参数imgsigma_list,分别代表输入的图像和高斯核的标准差列表。

  • retinex = np.zeros_like(img):创建了一个与输入图像img相同大小的全零数组retinex,用于存储Retinex结果。

  • for sigma in sigma_list::遍历sigma_list中的每个标准差值。

  • retinex += single_scale_retinex(img, sigma):调用single_scale_retinex函数计算单尺度Retinex,并将结果累加到retinex数组中。

  • retinex = retinex / len(sigma_list):将累加的Retinex结果除以sigma_list的长度,得到平均Retinex结果。

  • return retinex:返回计算得到的平均Retinex结果。

2.3 颜色恢复

颜色恢复
颜色恢复是Retinex算法中的一个重要步骤,它通过对各通道像素值进行对数运算,并乘以系数alpha和beta来实现颜色的恢复。具体步骤如下:

  1. 对输入图像的R、G、B三个通道进行分离。
  2. 分别对三个通道的像素值进行对数运算,得到对数图像。
  3. 将对数图像乘以系数alpha和beta,得到颜色恢复后的图像。

示例代码

def color_restoration(img, alpha, beta):
    img_sum = np.sum(img, axis=2, keepdims=True)
    # 对输入图像img沿着第二个维度求和,即对每个像素的RGB通道进行求和操作
    # keepdims=True表示保持结果的维度数量与原图像相同

    color_restoration = beta * (np.log10(alpha * img) - np.log10(img_sum))
    # 计算颜色恢复后的图像
    # np.log10(...) 对输入图像alpha * img 进行log10变换,将像素值转换为对数域
    # np.log10(img_sum) 对输入图像img_sum进行log10变换,将像素值转换为对数域
    # np.log10(...) - np.log10(...) 执行两个结果之间的减法运算

    return color_restoration

解释说明
这段代码实现了颜色恢复的功能。

  • def color_restoration(img, alpha, beta)::定义了一个函数color_restoration,接收三个参数imgalphabeta,分别代表输入的图像、颜色强度调整系数和颜色平衡系数。

  • img_sum = np.sum(img, axis=2, keepdims=True):对输入图像img沿着第二个维度(RGB通道)进行求和操作,即对每个像素的RGB通道进行求和。keepdims=True表示保持结果的维度数量与原图像相同,得到一个具有相同大小但通道数为1的数组img_sum

  • color_restoration = beta * (np.log10(alpha * img) - np.log10(img_sum)):根据给定的公式计算颜色恢复后的图像。np.log10(alpha * img)对输入图像alpha * img进行log10变换,将像素值转换为对数域;np.log10(img_sum)对输入图像img_sum进行log10变换,将像素值转换为对数域;最后通过一系列运算得到颜色恢复的结果存储在color_restoration变量中。

  • return color_restoration:返回颜色恢复后的图像。

2.4 最终图像处理

最终图像处理是将多尺度Retinex和颜色恢复两个操作结合起来,得到最终的增强图像。具体步骤如下:

  1. 将输入图像转换为浮点数类型,并加上1.0,避免出现除零错误。
  2. 调用多尺度Retinex算法对图像进行增强,得到增强后的图像。
  3. 调用颜色恢复算法对图像进行颜色恢复,得到颜色恢复后的图像。
  4. 对增强后的图像进行亮度和颜色的调整,得到最终的增强图像。
  5. 对最终的增强图像进行像素范围的限制,确保像素值在0-255之间。
  6. 将最终的增强图像转换为无符号整数类型,并返回。

代码示例

def retinex_process(img, sigma_list, G, b, alpha, beta):
    img = np.float64(img) + 1.0
    # 将输入图像转换为float64类型,并加上1.0,用于防止log运算时出现零值

    img_retinex = multi_scale_retinex(img, sigma_list)
    # 调用multi_scale_retinex函数对输入图像进行多尺度Retinex增强处理,
    # 得到增强后的图像img_retinex

    img_color = color_restoration(img, alpha, beta)
    # 调用color_restoration函数对输入图像进行颜色恢复处理,
    # 得到恢复后的图像img_color

    img_retinex = G * (img_retinex * img_color + b)
    # 对增强后的图像img_retinex与恢复后的图像img_color按照一定的公式进行加权融合,
    # 并加上一个常数b,得到最终的Retinex结果img_retinex

    for i in range(img_retinex.shape[2]):
        img_retinex[:, :, i] = np.clip(img_retinex[:, :, i], 0, 255)
    # 对每个通道的像素值进行裁剪,将超过0和255的值限制在0-255范围内

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

    return img_retinex

解释说明
这段代码实现了Retinex图像处理的流程。

  • def retinex_process(img, sigma_list, G, b, alpha, beta)::定义了一个函数retinex_process,接收六个参数imgsigma_listGbalphabeta,分别代表输入的图像、高斯核的标准差列表、融合权重系数G、常数b、颜色强度调整系数alpha和颜色平衡系数beta。

  • img = np.float64(img) + 1.0:将输入的图像img转换为float64类型,并加上1.0,用于防止log运算时出现零值。

  • img_retinex = multi_scale_retinex(img, sigma_list):调用multi_scale_retinex函数对输入图像进行多尺度Retinex增强处理,得到增强后的图像img_retinex

  • img_color = color_restoration(img, alpha, beta):调用color_restoration函数对输入图像进行颜色恢复处理,得到恢复后的图像img_color

  • img_retinex = G * (img_retinex * img_color + b):对增强后的图像img_retinex与恢复后的图像img_color按照一定的公式进行加权融合,并加上一个常数b,得到最终的Retinex结果img_retinex

  • for i in range(img_retinex.shape[2])::遍历图像img_retinex的第三个维度,即通道数。

  • img_retinex[:, :, i] = np.clip(img_retinex[:, :, i], 0, 255):对每个通道的像素值进行裁剪,将超过0和255的值限制在0-255范围内,使用np.clip函数实现。

  • img_retinex = np.uint8(img_retinex):将增强后的图像img_retinex转换为uint8类型,即8位无符号整型。

  • return img_retinex:返回处理后的Retinex结果图像。

3. Retinex算法的Python实现

基于OpenCV和NumPy库,我们可以很方便地实现Retinex算法。下面是Retinex算法的Python代码实现:

import cv2
import numpy as np

# 对图像进行单尺度 Retinex 处理
def single_scale_retinex(img, sigma):
    retinex = np.log10(img) - np.log10(cv2.GaussianBlur(img, (0, 0), sigma))
    return retinex

# 对图像进行多尺度 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('WechatIMG9.jpeg')

    # 尺度列表
    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)
    # 保存增强后的图片
    cv2.imwrite('a.jpg', img_retinex)

if __name__ == "__main__":
    main()

代码通过 Retinex 算法对图像进行增强,包括单尺度 Retinex 处理、多尺度 Retinex 处理和颜色恢复。

  • single_scale_retinex 函数:对图像进行单尺度 Retinex 处理,使用对数域操作计算图像的亮度分量。
  • multi_scale_retinex 函数:对图像进行多尺度 Retinex 处理,将多个尺度的 Retinex 处理结果相加并取平均。
  • color_restoration 函数:进行颜色恢复,计算图像的颜色分量。
  • retinex_process 函数:图像增强的主要函数,包括图像增强和颜色恢复操作。
  • main 函数:主函数,在这里读取输入图像,并设定参数,然后调用 retinex_process 函数进行图像增强。
  • 在窗口中显示原始图像和增强后的图像,并保存增强后的图像到文件。

效果展示
原图:

在这里插入图片描述

执行之后的图

在这里插入图片描述

对比图

在这里插入图片描述

4. 完结

期待下一次的更新哦!!!
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_33681891/article/details/131578763
今日推荐