利用OpenCV进行Tonemapping
背景
最近学习深度学习涉及到了一些HDR图片的读取,HDR全称是High-Dynamic Range,在显示HDR图片的时候,如果不进行色调映射,也就是Tone map的话,那显示出来的HDR图片就会很暗,所以我们需要映射之后再进行显示。
方法
方法1
在现有的论文中,一般会有一个tone map公式,这个公式的描述如下:
其中Ih是需要tone map的图片,μ是一个压缩的参数,在一般情况下取到5000,这个方法用代码写出来就是下面这样
def tonemapping(pic):
return np.log(1. + 5000. * pic) / np.log(1. + 5000.)
没有进行tone map前的HDR图:
可以看到HDR图片拥有很多细节,但是不进行映射的话,更本无法展示出来
利用这个方法进行tone map后的效果如图:
可以看到图片的细节已经展示了出来,但是这时候也发现了一个问题,图片的颜色偏淡,感觉雾蒙蒙的,这和论文里面经过色调映射后的效果有很大的差别,这时候我就开始寻找怎样进行映射可以展示出图片的细节,同时图片的颜色也尽可能的丰富。
方法2
我在寻找的时候,发现了OpenCV在内部已经实现了几种ToneMap的操作,分别是以下的五种:
cv2.createTonemapDrago()
cv2.createTonemapDurand{}
cv2.createTonemapReinhard{}
cv2.createTonemapMantiuk{}
cv2.createTonemap{}
这几个函数的关系如下:
这里参考了https://github.com/spmallick/learnopencv/blob/master/hdr/hdr.py里的tone map代码
# Tonemap using Drago's method to obtain 24-bit color image
print("Tonemaping using Drago's method ... ")
tonemapDrago = cv2.createTonemapDrago(1.0, 0.7)
ldrDrago = tonemapDrago.process(hdrDebevec)
ldrDrago = 3 * ldrDrago
cv2.imwrite("ldr-Drago.jpg", ldrDrago * 255)
print("saved ldr-Drago.jpg")
# Tonemap using Durand's method obtain 24-bit color image
print("Tonemaping using Durand's method ... ")
tonemapDurand = cv2.createTonemapDurand(1.5, 4, 1.0, 1, 1)
ldrDurand = tonemapDurand.process(hdrDebevec)
ldrDurand = 3 * ldrDurand
cv2.imwrite("ldr-Durand.jpg", ldrDurand * 255)
print("saved ldr-Durand.jpg")
# Tonemap using Reinhard's method to obtain 24-bit color image
print("Tonemaping using Reinhard's method ... ")
tonemapReinhard = cv2.createTonemapReinhard(1.5, 0, 0, 0)
ldrReinhard = tonemapReinhard.process(hdrDebevec)
cv2.imwrite("ldr-Reinhard.jpg", ldrReinhard * 255)
print("saved ldr-Reinhard.jpg")
# Tonemap using Mantiuk's method to obtain 24-bit color image
print("Tonemaping using Mantiuk's method ... ")
tonemapMantiuk = cv2.createTonemapMantiuk(2.2, 0.85, 1.2)
ldrMantiuk = tonemapMantiuk.process(hdrDebevec)
ldrMantiuk = 3 * ldrMantiuk
cv2.imwrite("ldr-Mantiuk.jpg", ldrMantiuk * 255)
print("saved ldr-Mantiuk.jpg")
结果如下:
可以看到经过不同的tone map算法,相同的HDR图片可以产生不同的图片,相较于上面的方法一,可以看到颜色会相较方法一会丰富很多
想法
为什么论文里面需要使用方法一这样的tone map方法呢?我的想法是这样,因为方法一是使用在计算Loss前的,GT和预测值都使用同样的的公式,所以这个Tonemap公式的作用其实是让网络的收敛更加的迅速,因为HDR图片的范围是比较窄的,不映射的话计算的Loss就会比较小,网络的收敛也会比较慢,这一点在论文里面也得到了体现。
所以方法一其实主要的作用是让计算更加的有效率,而不是最终展示的作用,那么如果需要将结果进行展示的话,可以使用其他的ToneMap方法或者直接使用OpenCV已经实现好的方法。
最后
如果大家有疑问或者发现我的文章有错误,都欢迎指出~