HDR tone mapping介绍

HDR and tone mapping

1.什么是HDR?

就是高动态图像。如何体现
查看 https://www.easyhdr.com/examples/ 这个网站上的例子:

在这里插入图片描述

3张曝光融合为一张, 似乎是挑出不同曝光图像中比较清晰的部分 进行融合。
比如选了 第一张欠曝图像中 的高光蓝天部分, 选了第二三张过曝图像 中的 一些低亮度 海岸部分。 最终融合一张 整体亮度适中的 HDR图像:这样既能看清蓝天,也能看清海岸。

那么是不是可以通过调整第二张图像的亮度来达到 HDR的效果呢? 比如压制高光蓝天,提亮低光海岸。答案也是可以的,有一些深度学习的方法也是这么做的,单张HDR或者图像增强。

如下面的例子:
在这里插入图片描述

https://learnopencv.com/high-dynamic-range-hdr-imaging-using-opencv-cpp-python/
https://docs.opencv.org/3.4/d2/df0/tutorial_py_hdr.html
https://zhuanlan.zhihu.com/p/38176640

2.为什么需要HDR?

因为现实场景的动态范围非常大,人眼的动态范围也比较宽广, HDR技术可以更好的表达场景,更好的符合人眼感知

在这里插入图片描述

sdr和 hdr图像:
在这里插入图片描述

3.hdr文件格式

hdr文件 是 float32类型,记录的是场景的亮度,与辐射是线性关系。
在 改网站上可以显示hdr图像:https://viewer.openhdr.org/

比如拖入nave.hdr文件可以得到:
在这里插入图片描述

右上角是曝光调节,可以看到不同曝光条件下的 图像。

这里我用python 实现了上面网站类似的效果:

根据不同的ev, 提取一定范围内直方图的数据,展示图片。

在这里插入图片描述

提取 乘上(2^ev)之后的[0, 1]范围内数据

img = np.clip(data * (2 ** ev), 0, 1) ** (1/2.2)

在这里插入图片描述

完整code:

def compute_luminance(input: np.ndarray):
    luminance = 0.2126 * input[:, :,
                         0] + 0.7152 * input[:, :,
                                       1] + 0.0722 * input[:, :, 2]
    return luminance


def map_luminance(input: np.ndarray, luminance: np.ndarray,
                  new_luminance: np.ndarray):
    output = np.zeros(input.shape)

    output[:, :, 0] = input[:, :, 0] * new_luminance / luminance
    output[:, :, 1] = input[:, :, 1] * new_luminance / luminance
    output[:, :, 2] = input[:, :, 2] * new_luminance / luminance
    return output

if __name__ == "__main__"
    file = r'D:\code_color\HDR-Tone-Mapping-and-Image-Upscaling-main\test image\hdr_images\vinesunset.hdr'
    data = cv2.imread(file, cv2.IMREAD_ANYDEPTH)[..., ::-1]
    print('rgb data info ')
    print(data.shape, data.dtype, data.min(), data.max(), data.mean())

    L = compute_luminance(data)
    print('L info ')
    print(L.shape, L.dtype, L.min(), L.max(), L.mean())

    L_log = np.log2(L)
    print('L log info ')
    print(L_log.shape, L_log.dtype, L_log.min(), L_log.max(), L_log.mean())

    bin_low = L_log.min()
    bin_high = L_log.max()
    bins_num = 500
    hist2, bins2 = np.histogram(L_log, bins_num, [bin_low, bin_high])

    plt.figure(figsize=(10, 3))
    plt.title("complete hist")
    plt.plot(np.linspace(bin_low, bin_high, bins_num), hist2, 'r-')
    plt.show()


    num_ev = 4
    hist_s = []
    img_s = []
    evs = -np.linspace(bin_low+4, bin_high, num_ev)
    print('evs : ', evs)
    for ev in evs:
        L0 = L * (2 ** ev)
        hist, bins= np.histogram(np.log2(L0), bins_num, [bin_low, bin_high])
        print(L0.min(), L0.max())
        img = np.clip(data * (2 ** ev), 0, 1) ** (1/2.2)

        hist_s.append(hist)
        img_s.append(img)


    # 画图
    plt.figure(figsize=(10, 3*num_ev))
    for i in range(len(evs)):
        ev = evs[i]
        hist = hist_s[i]
        ax = plt.subplot(num_ev, 1, i+1)
        ax.plot(np.linspace(bin_low, bin_high, bins_num), hist, 'r-')
        ax.plot((0, 0), (0, 0.6*hist.max()), 'k-')
        ax.set_title(str(np.round(ev, 2)))
        plt.xlim([bin_low, bin_high])

    plt.figure()
    for i in range(len(evs)):
        ev = evs[i]
        img = img_s[i]
        ax = plt.subplot(2, (num_ev+1)//2, i+1)
        ax.set_title(str(np.round(ev, 2)))
        plt.imshow(img)
    plt.show()

4.tone mapping

hdr的数据 覆盖的亮度比较大,而一般的传统设备可能无法显示 hdr数据(比如只能显示8bit的 sdr数据)

可以想到的是直接对hdr数据进行归一化,然后乘上255进行显示。但是这样显示有一个问题,就是比如一个hdr数据很多细节都在 比较小的数据上,如下图直方图所示:
在这里插入图片描述

这个时候线性归一化后,图像会整体比较暗,如下图:
在这里插入图片描述

一个正常的tone mapping方法可以得到正常的图像:
在这里插入图片描述

tone mapping 就是将hdr数据映射到 sdr设备上的方法。

这篇博客中有介绍一些常见的tone mapping方法:
比如Reinhard tone mapping, aces tone mapping等, 好像都是S-curve形状。

4.1 aces tone mapping

这里实现aced tone mapping 看下效果

在这里插入图片描述

def aces_tone_mapping(x):
    a = 2.51
    b = 0.03
    c = 2.43
    d = 0.59
    e = 0.14
    return (x * (a * x + b)) / (x * (c * x + d) + e)


def map_luminance(input, luminance, new_luminance, s=1):
    output = ((input / luminance[..., None])**s) * new_luminance[..., None]
    output = np.clip(output, 0, 1)
    return output

if __name__ == "__main__"
    # aces tone mapping
    x = L
    y = aces_tone_mapping(x)
    out_aces = map_luminance(data, x, y, 1)
    out_aces = out_aces ** (1 / 2.2)

    plt.figure()
    plt.subplot(121)
    plt.xscale('log')
    plt.plot(x[::100, ::100], y[::100, ::100], '+')

    plt.subplot(122)
    plt.imshow(out_aces)
    plt.show()

4.2 Fast Bilateral Filtering for the Display of High-Dynamic-Range Images

Durand and Julie Dorsey 基于 滤波 和 分层的 tone mapping方法
算法原理如下:
在这里插入图片描述

仿真实验效果:
在这里插入图片描述

python code:

def fast_bilateral_tone_mapping(data):
    contrast = 10
    L = compute_luminance(data)
    chrome = data / L[..., None]

    log_intensity = np.log10(L)

    base_layer = bilateral_filter(log_intensity, 7, 50, 50)

    detail_layer = log_intensity - base_layer

    compression_factor = np.log10(contrast) / (base_layer.max() - base_layer.min())
    log_abs_scale = base_layer.max() * compression_factor
    out_log_lum = base_layer * compression_factor + detail_layer - log_abs_scale
    out_lum = np.power(10, out_log_lum)

    out = chrome * out_lum[..., None]
    out = np.clip(out, 0, 1) ** (1 / 2.2)
    print('out : ', out.min(), out.max())
    plt.figure()
    plt.subplot(231)
    plt.title('map curve')
    plt.plot(L.reshape(-1)[::100], out_lum.reshape(-1)[::100], '.')

    plt.subplot(232)
    plt.title('L')
    plt.imshow(L, 'gray')

    plt.subplot(233)
    plt.title('chrome')
    plt.imshow(chrome)

    plt.subplot(234)
    plt.title('base')
    plt.imshow(base_layer, 'gray')

    plt.subplot(235)
    plt.title('detail_layer')
    plt.imshow(detail_layer, 'gray')

    plt.subplot(236)
    plt.title('out')
    plt.imshow(out)
    plt.show()


    return out
fast_bilateral_tone_mapping(data)

https://sites.google.com/site/ianschillebeeckx/cse555/hmwk1

5 参考

https://cloud.tencent.com/developer/article/1167088?areaSource=103001.6&traceId=r3KPIA5AV5GmTN3HDENpZ 色域映射介绍: HDR关键技术—色域映射
https://cloud.tencent.com/developer/article/1358173?areaSource=103001.5&traceId=r3KPIA5AV5GmTN3HDENpZ HDR关键技术:逆色调映射

本文主要介绍和了解hdr文件,以及tone mapping概念。
关于如何生成 HDR , tone mapping 算法, inverse tone mapping 方法等没有过多的介绍。

猜你喜欢

转载自blog.csdn.net/tywwwww/article/details/130368325
HDR