高动态范围图像(High-Dynamic Range,简称HDR),相比普通的图像,可以提供更多的动态范围和图像细节,根据不同的曝光时间的LDR(Low-Dynamic Range,低动态范围图像),并利用每个曝光时间相对应最佳细节的LDR图像来合成最终HDR图像。它能够更好的反映出真实环境中的视觉效果。[1]
HDR由两部分组成,动态曝光控制和光晕效果。先说动态曝光控制,通常,显示器能够显示R、G、B分量在[0,255]之间的像素值。而256个不同的亮度级别显然不能表示自然界中光线的亮度情况。举个例子,太阳的亮度是白炽灯亮度的几千倍或者被漫反射照亮的室内亮度的几万倍,这远远超出了显示器的亮度表示能力。HDR技术所要解决的问题就是在有限的亮度范围内表示出宽广的亮度范围。原理类似于照相机的曝光功能,通过算法调整光线亮度,将光线从高动态范围映射到低动态范围,从而得到得到令人信服的光照效果。
HDR的另一部分是光晕效果。人从暗处走到光亮的地方,瞳孔由于来不及收缩,眼睛会自己眯起来,以保护视网膜上的感光细胞。HDR通过对原始图像进行调整,可以模拟这种人眼自动适应光线变化的生理反应,产生类似于光晕的效果。[2]
HDR的图像合成compose,包含有以下几个步骤:[3]
Step0 图像配准,在图像有运动的情况下,需要精确配准输入图像
Step1 恢复不同曝光图像 (E1, E2, E3…)的辐射度图像 (S1, S2, S3…)
Step2 计算S1, S2, S3…的权重值w1(x,y), w2(x,y), w3(x,y),来合成最后一幅图
def readImagesAndTimes():
times = np.array([ 1/30.0, 0.25, 2.5, 15.0 ], dtype=np.float32)
filenames = ["resources/images/img_0.033.jpg", "resources/images/img_0.25.jpg",
"resources/images/img_2.5.jpg", "resources/images/img_15.jpg"]
images = []
for filename in filenames:
im = cv2.imread(filename)
images.append(im)
return images, times
images, times = readImagesAndTimes()
alignMTB = cv2.createAlignMTB()
alignMTB.process(images, images)
calibrateDebevec = cv2.createCalibrateDebevec()
responseDebevec = calibrateDebevec.process(images, times)
mergeDebevec = cv2.createMergeDebevec()
hdrDebevec = mergeDebevec.process(images, times, responseDebevec)
tonemapDrago = cv2.createTonemapDrago(1.0, 0.7)
ldrDrago = tonemapDrago.process(hdrDebevec)
ldrDrago = 3 * ldrDrago
cv2.imwrite("temp/ldr-Drago.jpg", ldrDrago * 255)
tonemapDurand = cv2.xphoto.createTonemapDurand(1.5,4,1.0,1,1)
ldrDurand = tonemapDurand.process(hdrDebevec)
ldrDurand = 3 * ldrDurand
tonemapReinhard = cv2.createTonemapReinhard(1.5, 0,0,0)
ldrReinhard = tonemapReinhard.process(hdrDebevec)
tonemapMantiuk = cv2.createTonemapMantiuk(2.2,0.85, 1.2)
ldrMantiuk = tonemapMantiuk.process(hdrDebevec)
ldrMantiuk = 3 * ldrMantiuk
处理结果:
参考
[1].https://baike.baidu.com/item/高动态光照渲染/3112921?fr=aladdin
[2].https://www.zhihu.com/question/19774840
[3].https://www.cnblogs.com/sunny-li/p/7050941.html