使用OpenCV 4.0进行高动态范围图像的色调映射

6
我希望创建一个脚本,将 .HDR 文件进行色调映射转换成 .JPG 文件。我查看了一些 OpenCV 教程,似乎它可以完成这个任务。
以下是我的脚本:
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 应该能够加载 .HDR 格式。
我尝试复制链接的教程,效果正确,因此问题在于 .HDR 图像,不知道有人知道该怎么办吗?
谢谢
编辑:我使用了这张HDR图像。因版权等原因提供链接而非直接下载。

1
你能提供一个我们可以复制的HDR输入图像样本吗? - Dan Mašek
1
@DanMašek编辑了原始帖子,并附上了我正在尝试的HDR链接。谢谢。 - AshenCZ
1个回答

7
你已经接近成功,只是犯了两个小错误。
第一个错误就是在不指定flags的情况下使用cv2.imread载入HDR图像。除非你调用它时加上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)

输出

Sample Output


1
谢谢。我已经阅读了imread选项,但可能错过了IMREAD_ANYDEPTH。我使用IMREAD_ANYCOLOR来获取我认为是IMREAD_ANYDEPTH的内容。第二个问题当然是由于复制+粘贴引起的,因为我正在尝试这两个教程,并试图将它们结合起来,因为没有一个单独的教程能够正常工作(因为第一个问题)。非常感谢。 - AshenCZ

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接