【python】通过深度图生成雾图(HAZERD)

博客提供了图像加雾的Matlab和Python版本完整代码,使用时需下载相关数据集,给出了数据集下载地址并提醒注意输入数据格式。展示了不同能见度下雾图效果,还提及相关论文及网址,下一步计划是对代码进行注释、优化和精简等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

​​​​​​​目录

 

 

完整代码matlab:

python版本:

使用时记得下载相关数据集:

效果:

官方:

下一步:


完整代码matlab:

参见:https://blog.csdn.net/Crystal_remember/article/details/119529529

python版本:

# -*- coding: gbk -*-
import os
import glob
import cv2, math
import numpy as np
from PIL import Image
import random
import numpy as np
import h5py
import os
from PIL import Image
import scipy.io

IMG_EXTENSIONS = [
    '.jpg', '.JPG', '.jpeg', '.JPEG',
    '.png', '.PNG', '.ppm', '.PPM', '.bmp', '.BMP',
]
#图片转矩阵
def pil_to_np(img_PIL):
    '''Converts image in PIL format to np.array.

    From W x H x C [0...255] to C x W x H [0..1]
    '''
    ar = np.array(img_PIL)

    if len(ar.shape) == 3:
        ar = ar.transpose(2, 0, 1)
    else:
        ar = ar[None, ...]

    return ar.astype(np.float32) / 255.

#矩阵转图片
def np_to_pil(img_np):
    '''Converts image in np.array format to PIL image.

    From C x W x H [0..1] to  W x H x C [0...255]
    '''
    ar = np.clip(img_np * 255, 0, 255).astype(np.uint8)

    if img_np.shape[0] == 1:
        ar = ar[0]
    else:
        ar = ar.transpose(1, 2, 0)

    return Image.fromarray(ar)

# 判断文件夹中是否有以上类型图片,没有则返回0
def is_image_file(filename):
    #如果不都为空、0、false,则any()返回true
    return any(filename.endswith(extension) for extension in IMG_EXTENSIONS)

#返回文件夹内文件绝对路径组成的列表
def make_dataset(dir):
    images = []
    assert os.path.isdir(dir), '%s is not a valid directory' % dir

    # os.walk(top[, topdown=True[, onerror=None[, followlinks=False]]]) 通过在目录树中游走输出在目录中的文件名,top返回三项(root,dirs,files),分别代表:
    # 当前正在遍历的这个文件夹的本身的地址;  list类型,内容是该文件夹中所有的目录的名字(不包括子目录);  list类型,内容是该文件夹中所有的文件(不包括子目录)
    for root, _, fnames in sorted(os.walk(dir)):
        for fname in fnames:
                #print(fname)
                #拼接出图片的地址,并加入到images列表
                path = os.path.join(root, fname)
                images.append(path)
    return images

def hazy_simu(img_name,depth_or_trans_name,save_dir,pert_perlin = 0,airlight=0.76,is_imdepth=1,visual_range = [0.05, 0.1, 0.2, 0.5, 1]):
    """
    This is the function for haze simulation with the parameters given by
    the paper:
    HAZERD: an outdoor scene dataset and benchmark for single image dehazing
    IEEE Internation Conference on Image Processing, Sep 2017
    The paper and additional information on the project are available at:
    https://labsites.rochester.edu/gsharma/research/computer-vision/hazerd/
    If you use this code, please cite our paper.

    IMPORTANT NOTE: The code uses the convention that pixel locations with a
    depth value of 0 correspond to objects that are very far and for the
    simulation of haze these are placed a distance of 2 times the visual
    range.

    Authors:
    Yanfu Zhang: yzh185@ur.rochester.edu
    Li Ding: l.ding@rochester.edu
    Gaurav Sharma: gaurav.sharma@rochester.edu

    Last update: May 2017

    python version update : Aug 2021
    Authors :
    Haoying Sun : 1913434222@qq.com

    parse inputs and set default values
    Set default parameter values. Some of these are used only if they are not
    passed in

    :param img_name: the directory and name of a haze-free RGB image, the name
                     should be in the format of ..._RGB.jpg
    :param depth_name: the corresponding directory and name of the depth map, in
                     .mat file, the name should be in the format of ..._depth.mat
    :param save_dir: the directory to save the simulated images
    :param pert_perlin: 1 for adding perlin noise, default 0
    :param airlight:  3*1 matrix in the range [0,1]
    :param visual_range: a vector of any size
    :return: image name of hazy image
    """
    visual_range = [0.05, 0.1, 0.2, 0.5, 1]  #  visual range in km #可自行调整,或者使用range函数设置区间,此时需要修改beta_param,尚未研究
    beta_param = 3.912     #Default beta parameter corresponding to visual range of 1000m
    # A = np.zeros((1, 1, 3))
    # A[0, 0, 0] = airlight
    # A[0, 0, 1] = airlight
    # A[0, 0, 2] = airlight
    A = airlight
    if save_dir != '':
        if not os.path.exists(save_dir):
            os.makedirs(save_dir)

    print('Simulating hazy image for:{}'.format(img_name))
    VR = random.choice(visual_range)
    print('Viusal value: {} km'.format(VR) )
    im1 = cv2.imread(img_name)
    img_pil = pil_to_np(im1)

    #convert sRGB to linear RGB
    I = srgb2lrgb(img_pil)
    if is_imdepth:
        depths = get_depth(depth_or_trans_name)
        d = depths/1000   # convert meter to kilometer

        #Set regions where depth value is set to 0 to indicate no valid depth to
        #a distance of two times the visual range. These regions typically
        #correspond to sky areas
        d = np.where(d==0,2*VR,d)
        if pert_perlin:
            d = d * ((perlin_noise(np.zeros(d.shape)) - 0.5) + 1)

        #convert depth map to transmission
        beta = beta_param / VR
        beta = np.ones(d.shape) * beta
        transmission = np.exp((-beta*d))
        transmission_3 = np.array([transmission,transmission,transmission])

        #Obtain simulated linear RGB hazy image.Eq. 3 in the HazeRD paper
        Ic = transmission_3 * I+ (1 - transmission_3) * A

    else:
        Ic = pil_to_np(depth_or_trans_name) * I + (1 - pil_to_np(depth_or_trans_name)) * A

    # convert linear RGB to sRGB
    I2 = lrgb2srgb(Ic)
    haze_img = np_to_pil(I2)

    return haze_img


def perlin_noise(im, decay=2):

    """
    ——————————————————————————————————————————————————————————————————————————————
                        非均匀雾(柏林噪声)通常用柏林噪声来模拟大气湍流引起的非均匀雾,论文
    Towards Simulating Foggy and Hazy Images and Evaluating Their Authenticity
    生成三个不同频率参数(f=130、60、10)的三维柏林噪声,并通过以下方法组合:
    noise = 1/3 Sum_i(noise_i/2^(i-1)),i从1到3
    求得的noise与消光系数相乘,带入到Eq.2,模拟非均匀雾。
    I = Iex + Op*Ial    EQ.1
    Iex = Ipexp(-βex * rp)   EQ.2
    O = 1 - exp(-βex * rp)   EQ.3
    Iex:目标反射光经过大气中微粒衰减;Ial:环境光经过微粒散射,形成背景光; Op:模糊度;βex:消光系数
    ——————————————————————————————————————————————————————————————————————————————_
        This is the function for adding perlin noise to the depth map. It is a
    simplified implementation of the paper:
    an image sunthesizer
    Ken Perlin, SIGGRAPH, Jul. 1985
    The bicubic interpolation is used, compared to the original version.
    Reference:
    HAZERD: an outdoor scene dataset and benchmark for single image dehazing
    IEEE International Conference on Image Processing, Sep 2017
    The paper and additional information on the project are available at:
    https://labsites.rochester.edu/gsharma/research/computer-vision/hazerd/
    If you use this code, please cite our paper.
    Input:
      im: depth map
      varargin{1}: decay term
    Output:
      im: result of transmission with perlin noise added
    Authors:
      Yanfu Zhang: yzh185@ur.rochester.edu
      Li Ding: l.ding@rochester.edu
      Gaurav Sharma: gaurav.sharma@rochester.edu
    Last update: May 2017
    :return:
    """
    (h, w, c) = im.shape
    i = 1
    l_bound = min(h,w)
    while i <= l_bound:
        #d = imresize(randn(i, i)*decay, im.shape, 'bicubic')
        d = cv2.resize(np.random.randn(i,i)*decay, im.shape, interpolation=cv2.INTER_CUBIC)
        im = im+d
        i = i*2 

    im = (im - np.min(im)) / (np.max(im) - np.min(im))
    return im

def srgb2lrgb(I0):
    gamma = ((I0 + 0.055) / 1.055)**2.4
    scale = I0 / 12.92
    return np.where (I0 > 0.04045, gamma, scale)

def lrgb2srgb(I1):
    gamma =  1.055*I1**(1/2.4)-0.055
    scale = I1 * 12.92
    return np.where (I1 > 0.0031308, gamma, scale)



#获取深度矩阵
def get_depth(depth_or_trans_name):
    #depth_or_trans_name为mat类型文件或者img类型文件地址
    data = scipy.io.loadmat(depth_or_trans_name)
    depths = data['imDepth'] #深度变量
    #print(data.keys())  #打印mat文件中所有变量
    depths = np.array(depths)
    return depths
def AddHaze1(img):
    img = cv2.imread(img)
    img = np.array(img)
    img_f = img
    (row, col, chs) = img.shape

    A = 0.5  # 亮度
    beta = 0.08  # 雾的浓度
    size = math.sqrt(max(row, col))  # 雾化尺寸
    center = (row // 2, col // 2)  # 雾化中心
    for j in range(row):
        for l in range(col):
            d = -0.04 * math.sqrt((j - center[0]) ** 2 + (l - center[1]) ** 2) + size
            td = math.exp(-beta * d)
            img_f[j][l][:] = img_f[j][l][:] * td + A * (1 - td)
    return Image.fromarray(img_f.astype(np.uint8))

#请修改以下路径
img_dir = 'I:\HazeRD\data\img'
depth_dir = 'I:\HazeRD\data\depth'
save_dir = 'I:\HazeRD\data\depth\simu' #存放生成雾图结果
img_list = make_dataset(img_dir)
depth_list = make_dataset(depth_dir)

# # 生成雾图结果可视化
# a = hazy_simu(img_list[0],depth_list[0],save_dir)
# Image.Image.show(a)
# cv2.waitKey(1000)

# #原始图片可视化
# img_name= img_list[0]
# im1 = cv2.imread(img_name)
# im1 = Image.fromarray(im1.astype(np.uint8))
# Image.Image.show(im1)
# cv2.waitKey(1000)

# #深度图可视化
# depth_name = depth_list[0]
# depths = get_depth(depth_name)
# im1 = Image.fromarray(depths.astype(np.uint8))
# Image.Image.show(im1)
# cv2.waitKey(1000)

使用时记得下载相关数据集:

下载地址见底部,注意输入数据格式一致,请下载原始数据!

目录安排如下:

效果:

原始图:

深度图:

能见度为1KM时的雾图情况:

 

能见度为0.2KM的雾图情况:

官方:


论文: HazeRD: An Outdoor Scene Dataset and Benchmark for Single Image Dehazing

网址: https://labsites.rochester.edu/gsharma/research/computer-vision/hazerd/

下一步:

代码注释、优化和精简!

输入数据格式限制问题优化!

透射图作为输入时可能会出现的问题优化!

第一部分: # -*- coding: gbk -*- import os import glob import cv2, math import numpy as np from PIL import Image import random import numpy as np import h5py import os from PIL import Image import scipy.io IMG_EXTENSIONS = [ '.jpg', '.JPG', '.jpeg', '.JPEG', '.png', '.PNG', '.ppm', '.PPM', '.bmp', '.BMP', ] #片转矩阵 def pil_to_np(img_PIL): '''Converts image in PIL format to np.array. From W x H x C [0...255] to C x W x H [0..1] ''' ar = np.array(img_PIL) if len(ar.shape) == 3: ar = ar.transpose(2, 0, 1) else: ar = ar[None, ...] return ar.astype(np.float32) / 255. #矩阵转片 def np_to_pil(img_np): '''Converts image in np.array format to PIL image. From C x W x H [0..1] to W x H x C [0...255] ''' ar = np.clip(img_np * 255, 0, 255).astype(np.uint8) if img_np.shape[0] == 1: ar = ar[0] else: ar = ar.transpose(1, 2, 0) return Image.fromarray(ar) # 判断文件夹中是否有以上类型片,没有则返回0 def is_image_file(filename): #如果不都为空、0、false,则any()返回true return any(filename.endswith(extension) for extension in IMG_EXTENSIONS) #返回文件夹内文件绝对路径组成的列表 def make_dataset(dir): images = [] assert os.path.isdir(dir), '%s is not a valid directory' % dir # os.walk(top[, topdown=True[, onerror=None[, followlinks=False]]]) 通过在目录树中游走输出在目录中的文件名,top返回三项(root,dirs,files),分别代表: # 当前正在遍历的这个文件夹的本身的地址; list类型,内容是该文件夹中所有的目录的名字(不包括子目录); list类型,内容是该文件夹中所有的文件(不包括子目录) for root, _, fnames in sorted(os.walk(dir)): for fname in fnames: #print(fname) #拼接出片的地址,并入到images列表 path = os.path.join(root, fname) images.append(path) return images def hazy_simu(img_name,depth_or_trans_name,save_dir,pert_perlin = 0,airlight=0.76,is_imdepth=1,visual_range = [0.05, 0.1, 0.2, 0.5, 1]): """ This is the function for haze simulation with the parameters given by the paper: HAZERD: an outdoor scene dataset and benchmark for single image dehazing IEEE Internation Conference on Image Processing, Sep 2017 The paper and additional information on the project are available at: https://labsites.rochester.edu/gsharma/research/computer-vision/hazerd/ If you use this code, please cite our paper. IMPORTANT NOTE: The code uses the convention that pixel locations with a depth value of 0 correspond to objects that are very far and for the simulation of haze these are placed a distance of 2 times the visual range. Authors: Yanfu Zhang: [email protected] Li Ding: [email protected] Gaurav Sharma: [email protected] Last update: May 2017 python version update : Aug 2021 Authors : Haoying Sun : [email protected] parse inputs and set default values Set default parameter values. Some of these are used only if they are not passed in :param img_name: the directory and name of a haze-free RGB image, the name should be in the format of ..._RGB.jpg :param depth_name: the corresponding directory and name of the depth map, in .mat file, the name should be in the format of ..._depth.mat :param save_dir: the directory to save the simulated images :param pert_perlin: 1 for adding perlin noise, default 0 :param airlight: 3*1 matrix in the range [0,1] :param visual_range: a vector of any size :return: image name of hazy image """
最新发布
03-24
评论 20
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Alocus_

如果我的内容帮助到你,打赏我吧

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

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

打赏作者

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

抵扣说明:

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

余额充值