[英]OpenCV MergeMertens gives different results in Python Vs. C++
When I run the HDR Mertens exposure fusion in Python I get weird colors artifact, that I don't get when I run the exact same function in c++. 当我在Python中运行HDR Mertens曝光融合时,我得到了奇怪的颜色伪影,而在c ++中运行完全相同的函数却没有。 (I just run the HDR Tutorial )
(我只是运行HDR教程 )
Seems to me like some problem with the data types, but I tried every option and nothing works. 在我看来,数据类型有些问题,但是我尝试了所有选项,但没有任何效果。 Am I doing something wrong?
难道我做错了什么?
I'm running Python 3.5 64-bit with OpenCV 3.0.0. 我正在运行带有OpenCV 3.0.0的Python 3.5 64位。
The exposures images were taken from Wikipedia: 1/30 sec , 1/4 sec , 2.5 sec , 15 sec . 曝光图像来自Wikipedia: 1/30秒 , 1/4秒 , 2.5秒 , 15秒 。
The Python code: 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)
The result I get in Python: 我在Python中得到的结果:
The result I get in C++: 我在C ++中得到的结果:
What happens here is caused by 8 bit overflow and underflow for some of the R, G, B subpixels. 这里发生的是由某些R,G,B子像素的8位上溢和下溢引起的。 Some of them are outside of the interval
[0.0 .. 1.0]
after the fusion, and when multiplied with 255, the result will be negative or above 255. 其中一些超出融合后的间隔
[0.0 .. 1.0]
,并且与255相乘时,结果将为负或大于255。
np.uint8
will truncate the results, and keep only the least significant 8 bits, so for example: np.uint8
将截断结果,并仅保留最低有效8位,因此例如:
a value of -2
will be stored as 254
值
-2
将存储为254
a value of 257
will be stored as 1
值
257
将被存储为1
This can be solved by clipping the results in the range [0 .. 255]
, replacing 这可以通过将结果剪切到
[0 .. 255]
范围内,替换为
resFusion_8bit = np.uint8(resFusion*255)
with 同
np.clip(resFusion*255, 0, 255, out=resFusion)
resFusion_8bit = resFusion.astype('uint8')
Or, it is possible to pass directly the values multiplied with 255 to imwrite
, without converting them first to uint8
and it will take care of the clipping. 或者,可以直接将乘以255的值传递给
imwrite
,而无需先将它们转换为uint8
,这样就可以处理剪切。 It would be the same as it is done in the provided C++ example. 与提供的C ++示例中的操作相同。 So, the script can be rewritten as:
因此,脚本可以重写为:
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)
(Note that I replaced the file extensions with .JPG
- uppercase, as this is the original name on Wikipedia and I've ran this on Linux, where filenames are case sensitive.) (请注意,我用
.JPG
替换了文件扩展名-大写,因为这是Wikipedia的原始名称,并且我已经在Linux上运行了此扩展名,文件名区分大小写。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.