图像加雾算法的研究与应用

目录

前言

一、图像加雾

1、基于RGB通道的雾图合成

2、基于大气散射模型的雾图合成

3、基于深度学习的雾图合成

4、基于Lightroom Classic实现软件加雾

5、基于深度图的方法实现加雾

二、开源的数据集

三、参考文章


 

前言

在去雾任务当中,训练和评估去雾算法需要大量的带有雾霾和无雾霾的图像对。由于实际拍摄的带雾霾的图像不易获得并且不可控,因此研究者常常通过加雾(Image Fogging)技术来人工生成含雾图像,以丰富数据集。这不仅有助于生成多样化的训练数据,还能在控制实验中评估去雾算法的性能。本文将探讨图像加雾的基本原理和常用方法,并介绍一些用于图像加雾的具体技术。

一、图像加雾

1、基于RGB通道的雾图合成

import cv2
import numpy as np

def addfog_channels(image, fog_intensity=0.5, fog_color_intensity=255):
    """
    对图像 RGB 通道应用雾效。

    参数:
        image: 输入图像(numpy数组)。
        fog_intensity: 雾的强度(0到1)。
        fog_color_intensity: 雾的颜色强度(0到255).不宜过小, 建议大于180
    """
    fog_intensity = np.clip(fog_intensity, 0, 1)
    fog_layer = np.ones_like(image) * fog_color_intensity
    fogged_image = cv2.addWeighted(image, 1 - fog_intensity, fog_layer, fog_intensity, 0)

    return fogged_image

image = cv2.imread('1.png')
fog_intensity = 0.5
fogged_image = addfog_channels(image, fog_intensity)

cv2.imshow('Original Image', image)
cv2.imshow('Fogged Image', fogged_image)
cv2.imwrite('fogged_image.jpg', fogged_image)
cv2.waitKey(0)
cv2.destroyAllWindows()

这种方法就是就像是在上面添加了一层纱雾。

2b9e5592e0044d7abb019735bde869cb.png

2、基于大气散射模型的雾图合成

大气散射模型: 大气散射是指光线在大气中传播时,由于空气中的微小颗粒和气体分子的散射,使得光线强度随着传播距离的增加而衰减。根据贝尔-朗伯定律(Beer-Lambert Law),光强度 eq?I 可以表示为:

eq?I%28d%29%3DI_%7B0%7D%5Ccdot%20e%5E%7B-%5Cbeta%20d%7D

其中:

  • eq?I_%7B0%7D 是初始光强度。
  • eq?%5Cbeta  是衰减系数,控制雾霾的浓度。
  • d   是光线传播的距离。

雾霾效果模拟:对于图像中的每一个像素,计算其到中心点的距离 d。使用指数衰减函数

eq?td%20%3D%20e%5E%7B-%5Cbeta%20d%7D计算雾霾的强度。调整每个像素的亮度,使其受到雾霾的影响。具体公式为:

new_pixel=original_pixel×td+brightness×(1−td)

其中 brightness 参数控制了雾霾的亮度。

下面让我们实现这个算法:

import numpy as np


def addfog(image, beta=0.05, brightness=0.5):
    """
    对输入的图像添加雾霾效果。

    Args:
        image (numpy.ndarray): 输入的图像,范围在0-255.
        beta (float, optional): 控制雾霾效果的参数.beta值越大,雾霾效果越明显.默认为0.05.
        brightness (float, optional): 雾霾的亮度值.该值越大,图像整体亮度越高.默认为0.5.

    Returns:
        numpy.ndarray: 添加雾霾效果后的图像,数据类型为uint8,范围在0-255。
    """
    img_f = np.array(image, dtype=np.float32) / 255.0
    row, col, chs = image.shape
    size = np.sqrt(max(row, col))  # Atomization size
    center = (row // 2, col // 2)  # Atomization center
    for j in range(row):
        for l in range(col):
            d = -0.04 * np.sqrt((j - center[0]) ** 2 + (l - center[1]) ** 2) + size
            td = np.exp(-beta * d)
            img_f[j][l][:] = img_f[j][l][:] * td + brightness * (1 - td)
    img_f = np.clip(img_f * 255, 0, 255).astype(np.uint8)
    return img_f


if __name__ == '__main__':
    import pyzjr
    path = r'1.png'
    image = pyzjr.imreader(path)
    print(image.shape)
    image_fog = addfog(image, beta=0.08, brightness=0.8)
    print(image_fog.shape)
    pyzjr.display("Comparison between original image and fogged image",
                  [[image, image_fog]], 0.8)

关于光线传播的距离d,它的系数-0.04应该是一个经验值,主要是用于调整距离对雾霾强度的影响。 可以根据实际效果进行调整,较小的系数会使距离对雾霾效果的影响减小,反之则增大。添加 size 是用来调节雾霾的范围大小的。通常情况下,雾化效果在中心点附近比较强烈,随着距离中心点的增加,雾化效果逐渐减弱。

加雾效果如下所示: 

2ba21f8e38fe4cfb95839fa846fe3e9a.png

在运行期间,时间明显比较长,现在我们来写一个优化的版本吧

这个时间长主要是因为这个嵌套循环,所以我们可以利用NumPy的矢量化操作来提高计算效率,可以使用 np.ogrid 生成行和列的索引,并计算每个像素点到中心点的距离。计算 td 采用矢量化方式,避免使用双重循环,提高效率。用 [..., np.newaxis] 进行广播,使得每个通道都应用相同的雾霾效果。这样就能显著提升大图像的处理速度,特别是在高分辨率图像上效果明显。

import numpy as np


def addfogv1(image, beta=0.05, brightness=0.5):
    """
    对输入的图像添加雾霾效果。

    Args:
        image (numpy.ndarray): 输入的图像,范围在0-255.
        beta (float, optional): 控制雾霾效果的参数.beta值越大,雾霾效果越明显.默认为0.05.
        brightness (float, optional): 雾霾的亮度值.该值越大,图像整体亮度越高.默认为0.5.

    Returns:
        numpy.ndarray: 添加雾霾效果后的图像,数据类型为uint8,范围在0-255。
    """
    img_f = np.array(image, dtype=np.float32) / 255.0
    row, col, chs = image.shape
    size = np.sqrt(max(row, col))  # Atomization size
    center = (row // 2, col // 2)  # Atomization center
    for j in range(row):
        for l in range(col):
            d = -0.04 * np.sqrt((j - center[0]) ** 2 + (l - center[1]) ** 2) + size
            td = np.exp(-beta * d)
            img_f[j][l][:] = img_f[j][l][:] * td + brightness * (1 - td)
    img_f = np.clip(img_f * 255, 0, 255).astype(np.uint8)
    return img_f

def addfogv2(image, beta=0.05, brightness=0.5):
    """
    对输入的图像添加雾霾效果的高效实现。

    Args:
        image (numpy.ndarray): 输入的图像,范围在0-255.
        beta (float, optional): 控制雾霾效果的参数. beta值越大, 雾霾效果越明显. 默认为0.05.
        brightness (float, optional): 雾霾的亮度值. 该值越大, 图像整体亮度越高. 默认为0.5.

    Returns:
        numpy.ndarray: 添加雾霾效果后的图像,数据类型为uint8,范围在0-255。
    """
    img_f = image.astype(np.float32) / 255.0
    row, col, chs = image.shape
    size = np.sqrt(max(row, col))  # Atomization size
    center = (row // 2, col // 2)  # Atomization center
    y, x = np.ogrid[:row, :col]
    dist = np.sqrt((x - center[1])**2 + (y - center[0])**2)
    d = -0.04 * dist + size
    td = np.exp(-beta * d)
    img_f = img_f * td[..., np.newaxis] + brightness * (1 - td[..., np.newaxis])
    img_f = np.clip(img_f * 255, 0, 255).astype(np.uint8)
    return img_f

if __name__ == '__main__':
    import pyzjr
    from pyzjr.dlearn.tools import Runcodes
    path = r'1.png'
    image = pyzjr.imreader(path)
    with Runcodes("加雾算法v1版本"):
        image_fogv1 = addfogv1(image, beta=0.08, brightness=0.8)
    with Runcodes("加雾算法v2版本"):
        image_fogv2 = addfogv2(image, beta=0.08, brightness=0.8)
    pyzjr.display("Comparison between original image and fogged image",
                  [[image_fogv1, image_fogv2]], 0.8)

加雾v1与v2版本的效果: 

92b0fc143f6d4461b750c0080e47dbe9.png

在时间对比上有很大提升

加雾算法v1版本: 3.43186 sec;加雾算法v2版本: 0.03255 sec

3、基于深度学习的雾图合成

利用成对数据训练模型,基于生成对抗网络(GAN)或者自编码器(Autoencoder)实现的深度学习方法可以实现端到端的合成雾图。然而,由于这些方法同样需要训练数据,合成的雾图和真实雾图之间可能存在一定的差异。

除此之外,我一直在思考一般我们做的去雾任务,能不能反过来做,把去雾的输入输出反过来训练,即将清晰图像作为输入,雾图像作为输出来训练模型,一般的模型都可以做到加雾任务。这种反向的方法,可能存在诸多的问题,但用深度学习的方法应该能够更好的控制雾的浓度和分布。

 

4、基于Lightroom Classic实现软件加雾

打开Lrc软件,左上角点击文件,导入照片和视频

b759db49bee94f6d9dc0c49311ee0e7c.png

点击图库,选择图片,修改图片,点击基本,调整去朦胧的值,往小的调整。 

2c57a6f11f684906a291f799618f6af3.png

这是拉到了-100的效果图 

fbbde51bd994406f98552094f037716c.png

如果想要恢复原来的照片,点击右下角「复位」按钮,就可以使照片恢复到最初的样子。也可以使用快捷键ctrl+z。

这是拉到了+100的效果图 

592673811aff44a381eee37a286f142b.png

比起原图也更加清晰,我觉得可以采用这样的方式去丰富我们的数据集。

 

5、基于深度图的方法实现加雾

Synscapes这个数据集很大,有180多个G,你可以从这里进行下载,全部下载完之后才能解压。

Synscapes data set (liu.se)

从exr文件读取深度信息并进行可视化

import OpenEXR
import numpy as np
import Imath
import cv2

def synscapes_depth_as_disparity(depth_image):
    """将Synscapes深度图像转换为视差图像。"""
    # 将深度图归一化到0-1范围,并将深度值转换为视差值
    normalized_depth_image = depth_image / np.max(depth_image)
    disparity_image = 1.0 / (normalized_depth_image + 1e-5)

    # 将视差图归一化到0-255范围
    normalized_disparity_image = (disparity_image - np.min(disparity_image)) / (
                np.max(disparity_image) - np.min(disparity_image)) * 255
    normalized_disparity_image = normalized_disparity_image.astype(np.uint8)

    return normalized_disparity_image

def read_depth_from_exr(exr_file_path):
    """使用OpenEXR库打开指定的EXR文件 """
    exr_file = OpenEXR.InputFile(exr_file_path)
    header = exr_file.header()
    width = header['dataWindow'].max.x + 1
    height = header['dataWindow'].max.y + 1

    pixel_type = Imath.PixelType(Imath.PixelType.FLOAT)
    z_channel = exr_file.channel('Z', pixel_type=pixel_type)
    z_buffer = np.frombuffer(z_channel, dtype=np.float32)
    z_buffer = z_buffer.reshape((height, width))

    return z_buffer


if __name__=="__main__":
    exr_file_path = r"F:\dataset\Dehazy\synscapes\Synscapes\img\depth\3.exr"
    depth_image = read_depth_from_exr(exr_file_path)
    normalized_disparity_image = synscapes_depth_as_disparity(depth_image)

    cv2.imshow("Disparity Image", normalized_disparity_image)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

f236ba94b9544ed2ac342da1f4d6d79e.png

加雾效果对比图

4901a9aefa4d4ead9b306e6107f92cb0.png

200702dece5b49b49131b724ee266c26.png

具体工作请看此部分:

深度图的方法实现加雾,Synscapes数据集以及D455相机拍摄为例-CSDN博客

二、开源的数据集

ITS, SOTS, OHAZE, Dense-haze下载路径

dataset - Google Drivehttps://drive.google.com/drive/folders/1mHr9p-c895tFtyRLz1JEeEGAurTmj_v-RSHaze、RESIDE-OUT、RESIDE-IN、RESIDE-6K

data - Google Drivehttps://drive.google.com/drive/folders/1oaQSpdYHxEv-nMOB7yCLKfw2NDCJVtrx大家找开源数据集可以从近两年的去雾的论文的开源仓库里面找到。

三、参考文章

数据增强:图片加雾效果实现Python_图像加雾算法-CSDN博客

https://www.scirp.org/pdf/jcc_2021110215052004.pdf

域适应加雾代码:通过《bringing old photos back to life 》_生成雾图-CSDN博客

如何在 Lightroom 中使用去朦胧功能?_lightroom去朦胧-CSDN博客

 

  • 25
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: Matlab图像去雾算法是对雾霾天气下的图像进行预处理的一种方法,通过去除图像中的雾霾,使得图像更加清晰,并提高图像的质量。通常采用的方法是基于暗通道先验的图像去雾算法。 暗通道先验是指图像中每个像素的RGB三个通道中,最小值通道被视为暗通道,即该通道中像素值最小的一个。在雾霾图像中,由于雾霾的存在,所有的像素值都会受到一些衰减,因此最小值通道对应的像素值就会比较小,在去雾过程中被广泛使用。 去雾的过程可以分为以下步骤: 1.计算暗通道:对于一幅输入图像,分别计算RGB三个通道中的最小值,然后对这些最小值进行平滑处理,以消除噪声。 2.估算全局大气光:通过在暗通道中寻找最大值,可以估计出图像的全局大气光。 3.计算透射率:通过计算每个像素与全局大气光之间的比值,可以得到图像中每个像素的透射率。 4.修复图像:将透射率应用到原始图像上,从而去除雾霾,并还原图像的清晰度。 Matlab图像去雾算法可以通过编程实现,具有较高的效率和精度,是处理雾霾图像的一种有效方法。 ### 回答2: Matlab图像去雾算法可以帮助我们有效地去除在图像中产生的雾气,使得图片更加清晰、真实、明亮。相比于人工处理,Matlab图像去雾算法可以更快捷、准确地处理大量的图片,因此在工业生产、图像识别、科学研究等领域有着广泛的应用。 Matlab图像去雾算法的基本原理是通过对图像的颜色、亮度、对比度、饱和度等方面进行调整,消除雾气的影响,提升图像的质量。首先,需要通过雾气模型来了解图像内部存在的雾气浓度、雾滴大小、透射率等参数,然后根据这些参数运用指定的公式进行雾气去除处理。同时,还需要考虑图像的噪声、锐度、色彩等因素,通过调整这些参数,最终呈现出更加清晰、亮丽、真实的图像。 总的来说,Matlab图像去雾算法是一项复杂而重要的图像处理技术,在许多领域都有广泛的应用。相比于传统的图像处理方法,它能更加快速地处理大量的图像,并且能够保证较高的准确度和清晰度,因此越来越受到人们的重视和使用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

夏天是冰红茶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值