使用 OpenCV 4.0 对 HDR 图像进行色调映射
Tone mapping a HDR image using OpenCV 4.0
我想创建一个脚本,它接受一个 .HDR
文件并将其色调映射到 .JPG
。看了几个OpenCV tutorials,好像应该可以做到。
我写了这个脚本:
import cv2
import numpy as np
filename = "image/gg.hdr"
im = cv2.imread(filename)
cv2.imshow('', im.astype(np.uint8))
cv2.waitKey(0)
tonemapDurand = cv2.createTonemapDurand(2.2)
ldrDurand = tonemapDurand.process(im.copy())
new_filename = filename + ".jpg"
im2_8bit = np.clip(ldrDurand * 255, 0, 255).astype('uint8')
cv2.imwrite(new_filename, ldrDurand)
cv2.imshow('', ldrDurand.astype(np.uint8))
根据教程应该可行。不过,我最终得到了一张黑色图像。我已经验证它保存的结果是 .JPG
,并且输入图像(1.6 兆像素 HDR 环境图)是有效的 .HDR
.
OpenCV 应该能够根据 the documentation.
加载 .HDR
s
我已经尝试重现教程 linked 并且工作正常,所以问题出在 .HDR
图像中,有人知道该怎么做吗?
谢谢
编辑:我使用了 this HDR image。由于版权等原因,提供 link 而不是直接下载
除了两个小错误外,你几乎完成了。
第一个错误是使用 cv2.imread
to load the HDR image without specifying any flags. Unless you call it with IMREAD_ANYDEPTH
,数据将缩小到 8 位,您将失去所有高动态范围。
当您指定 IMREAD_ANYDEPTH
时,图像将以 32 位浮点格式加载。这通常具有 [0.0, 1.0] 范围内的强度,但由于是 HDR,该值超过 1.0(在这种特殊情况下,它们高达约 22)。这意味着您将无法通过简单地将数据转换为 np.uint8
来可视化它(以有用的方式)。您也许可以先将其归一化到标称范围内,或者使用缩放和裁剪方法……任何您认为合适的方法。由于早期的可视化与结果无关,我将跳过它。
第二个问题很简单。您正确地将色调映射图像缩放并剪裁回 np.uint8
,但您从未使用过它。
脚本
import cv2
import numpy as np
filename = "GoldenGate_2k.hdr"
im = cv2.imread(filename, cv2.IMREAD_ANYDEPTH)
tonemapDurand = cv2.createTonemapDurand(2.2)
ldrDurand = tonemapDurand.process(im)
im2_8bit = np.clip(ldrDurand * 255, 0, 255).astype('uint8')
new_filename = filename + ".jpg"
cv2.imwrite(new_filename, im2_8bit)
输出
我想创建一个脚本,它接受一个 .HDR
文件并将其色调映射到 .JPG
。看了几个OpenCV tutorials,好像应该可以做到。
我写了这个脚本:
import cv2
import numpy as np
filename = "image/gg.hdr"
im = cv2.imread(filename)
cv2.imshow('', im.astype(np.uint8))
cv2.waitKey(0)
tonemapDurand = cv2.createTonemapDurand(2.2)
ldrDurand = tonemapDurand.process(im.copy())
new_filename = filename + ".jpg"
im2_8bit = np.clip(ldrDurand * 255, 0, 255).astype('uint8')
cv2.imwrite(new_filename, ldrDurand)
cv2.imshow('', ldrDurand.astype(np.uint8))
根据教程应该可行。不过,我最终得到了一张黑色图像。我已经验证它保存的结果是 .JPG
,并且输入图像(1.6 兆像素 HDR 环境图)是有效的 .HDR
.
OpenCV 应该能够根据 the documentation.
加载.HDR
s
我已经尝试重现教程 linked 并且工作正常,所以问题出在 .HDR
图像中,有人知道该怎么做吗?
谢谢
编辑:我使用了 this HDR image。由于版权等原因,提供 link 而不是直接下载
除了两个小错误外,你几乎完成了。
第一个错误是使用 cv2.imread
to load the HDR image without specifying any flags. Unless you call it with IMREAD_ANYDEPTH
,数据将缩小到 8 位,您将失去所有高动态范围。
当您指定 IMREAD_ANYDEPTH
时,图像将以 32 位浮点格式加载。这通常具有 [0.0, 1.0] 范围内的强度,但由于是 HDR,该值超过 1.0(在这种特殊情况下,它们高达约 22)。这意味着您将无法通过简单地将数据转换为 np.uint8
来可视化它(以有用的方式)。您也许可以先将其归一化到标称范围内,或者使用缩放和裁剪方法……任何您认为合适的方法。由于早期的可视化与结果无关,我将跳过它。
第二个问题很简单。您正确地将色调映射图像缩放并剪裁回 np.uint8
,但您从未使用过它。
脚本
import cv2
import numpy as np
filename = "GoldenGate_2k.hdr"
im = cv2.imread(filename, cv2.IMREAD_ANYDEPTH)
tonemapDurand = cv2.createTonemapDurand(2.2)
ldrDurand = tonemapDurand.process(im)
im2_8bit = np.clip(ldrDurand * 255, 0, 255).astype('uint8')
new_filename = filename + ".jpg"
cv2.imwrite(new_filename, im2_8bit)
输出