OpenCV Python HDR
【目标】
- 学习如何从曝光序列生成和显示HDR图像。
- 使用曝光融合来合并曝光序列。
【理论】
高动态范围成像(HDRI或HDR)是一种用于成像和摄影的技术,用于再现比标准数字成像或摄影技术更大的动态范围的光度。虽然人眼可以适应广泛的光照条件,但大多数成像设备每个通道使用8位,因此我们只能使用256级。当我们拍摄真实世界的场景时,明亮的区域可能曝光过度,而黑暗的区域可能曝光不足,所以我们不能用一次曝光来捕捉所有的细节。HDR成像适用于每个通道使用8位以上的图像(通常是32位浮点值),允许更宽的动态范围。
获取HDR图像有不同的方法,但最常见的是使用不同曝光值拍摄的场景照片。要组合这些曝光,了解相机的响应函数是很有用的,有算法可以估计它。HDR图像合并后,必须将其转换回8位才能在通常的显示器上查看。这个过程被称为音调映射。当场景或相机的物体在镜头之间移动时,会出现额外的复杂性,因为不同曝光的图像应该被注册和对齐。
在本教程中,我们展示了2种算法(Debevec, Robertson)从曝光序列生成和显示HDR图像,并演示了一种称为曝光融合的替代方法(Mertens),该方法产生低动态范围图像,不需要曝光时间数据。此外,我们还估计了摄像机响应函数(CRF),这对许多计算机视觉算法都有很大的价值。HDR管道的每一步都可以使用不同的算法和参数来实现,所以请查看参考手册来了解它们。
【代码】
import numpy as np
import cv2
# 1. Loading exposure images into a list
img_fn = ["assets/img0.jpg", "assets/img1.jpg", "assets/img2.jpg", "assets/img3.jpg"]
img_list = [cv2.imread(fn) for fn in img_fn]
# 曝光时间
exposure_times = np.array([15.0, 2.5, 0.25, 0.0333], dtype=np.float32)
# 2. Merge exposures into HDR image
merge_debevec = cv2.createMergeDebevec()
hdr_debevec = merge_debevec.process(img_list, times=exposure_times.copy())
merge_robertson = cv2.createMergeRobertson()
hdr_robertson = merge_robertson.process(img_list, times=exposure_times.copy())
# 3. Tonemap HDR image
tonemap1 = cv2.createTonemap(gamma=2.2)
res_debevec = tonemap1.process(hdr_debevec.copy())
res_robertson = tonemap1.process(hdr_robertson.copy())
# 4. Merge exposures using Mertens fusion
merge_mertens = cv2.createMergeMertens()
res_mertens = merge_mertens.process(img_list)
# 5. Convert to 8-bit and save
res_debevec_8bit = np.clip(res_debevec*255, 0, 255).astype('uint8')
res_robertson_8bit = np.clip(res_robertson*255, 0, 255).astype('uint8')
res_mertens_8bit = np.clip(res_mertens*255, 0, 255).astype('uint8')
cv2.imshow("ldr_debevec.jpg", res_debevec_8bit)
cv2.imshow("ldr_robertson.jpg", res_robertson_8bit)
cv2.imshow("fusion_mertens.jpg", res_mertens_8bit)
cv2.waitKey(0)
cv2.destroyAllWindows()
【接口】
cv2.MergeDebevec.process( src, times, response[, dst] ) -> dst
cv2.MergeDebevec.process( src, times[, dst] ) -> dst
cv2.MergeRobertson.process( src, times, response[, dst] ) -> dst
cv2.MergeRobertson.process( src, times[, dst] ) -> dst
cv2.MergeMertens.process( src, times, response[, dst] ) -> dst
cv2.MergeMertens.process( src[, dst] ) -> dst
【参考】
- High Dynamic Range (HDR)
- Paul E Debevec and Jitendra Malik. Recovering high dynamic range radiance maps from photographs. In ACM SIGGRAPH 2008 classes, page 31. ACM, 2008. [56]
- Mark A Robertson, Sean Borman, and Robert L Stevenson. Dynamic range improvement through multiple exposures. In Image Processing, 1999. ICIP 99. Proceedings. 1999 International Conference on, volume 3, pages 159–163. IEEE, 1999. [206]
- Tom Mertens, Jan Kautz, and Frank Van Reeth. Exposure fusion. In Computer Graphics and Applications, 2007. PG’07. 15th Pacific Conference on, pages 382–390. IEEE, 2007. [169]
- Images from Wikipedia-HDR
- HDR imaging