当我在Python中运行HDR Mertens曝光融合时,我得到了奇怪的颜色伪影,而在c ++中运行完全相同的函数却没有。(我只是运行HDR教程)
在我看来,数据类型有些问题,但是我尝试了所有选项,但没有任何效果。难道我做错了什么?
我正在使用OpenCV 3.0.0运行Python 3.5 64位。
曝光图像来自Wikipedia: 1/30秒,1/4秒,2.5秒,15秒。
Python代码:
import cv2
import numpy as np
img_fn = ["640px-StLouisArchMultExpEV+4.09.jpg",
"640px-StLouisArchMultExpEV+1.51.jpg",
"640px-StLouisArchMultExpEV-1.82.jpg",
"640px-StLouisArchMultExpEV-4.72.jpg"]
img_list = [cv2.imread(fn) for fn in img_fn]
# Exposure fusion using Mertens
mergeMertens = cv2.createMergeMertens()
resFusion = mergeMertens.process(img_list)
# Convert datatype to 8-bit and save
resFusion_8bit = np.uint8(resFusion*255)
cv2.imwrite("fusion.png", resFusion_8bit)
我在Python中得到的结果:
我在C ++中得到的结果:
这里发生的是由某些R,G,B子像素的8位上溢和下溢引起的。其中一些超出[0.0 .. 1.0]
融合后的时间间隔,并且与255相乘时,结果将为负或大于255。
np.uint8
将截断结果,并仅保留最低有效8位,因此例如:
的值-2
将存储为254
的值257
将存储为1
这可以通过将范围内的结果剪裁[0 .. 255]
,替换来解决
resFusion_8bit = np.uint8(resFusion*255)
和
np.clip(resFusion*255, 0, 255, out=resFusion)
resFusion_8bit = resFusion.astype('uint8')
或者,可以将乘以255的值直接传递给imwrite
,而无需先将其转换为uint8
,这样就可以进行裁剪。与提供的C ++示例中的操作相同。因此,脚本可以重写为:
import cv2
img_fn = ["640px-StLouisArchMultExpEV+4.09.JPG",
"640px-StLouisArchMultExpEV+1.51.JPG",
"640px-StLouisArchMultExpEV-1.82.JPG",
"640px-StLouisArchMultExpEV-4.72.JPG"]
img_list = [cv2.imread(fn) for fn in img_fn]
# Exposure fusion using Mertens
mergeMertens = cv2.createMergeMertens()
resFusion = mergeMertens.process(img_list)
# Save
cv2.imwrite("fusion.png", resFusion*255)
(请注意,我将文件扩展名替换为.JPG
-大写,因为这是Wikipedia的原始名称,并且我已经在Linux上运行了此扩展名,文件名区分大小写。)
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句