本文共 2938 字,大约阅读时间需要 9 分钟。
本章旨在帮助开发者理解如何通过多帧曝光生成并展示高动态范围(HDR)图像。我们将重点介绍两种经典算法——Debevec和Robertson——以及一种替代方法Mertens融合,展示如何根据不同曝光时间合并图像。同时,我们还将探讨如何通过相机响应函数(CRF)优化HDR合成结果。
HDR成像能够捕捉比标准成像更广的亮度范围,这对于复杂的光照场景至关重要。相机通常以8位(256级)存储图像数据,无法在同一帧中同时捕捉明暗细节。HDR技术通过多帧曝光(不同曝光时间的图像)合成一张完整的高动态范围图像。
目前有多种获取HDR图像的方法,其中最常见的是拍摄不同曝光时间的场景图像。合并这些图像需要了解相机响应函数和估算算法的特性。合并后,HDR图像需转换回8位以适配常规显示器,但这个过程称为色调映射可能会引入额外复杂性。
在这个教程中,我们将使用四张曝光图像,曝光时间分别为15、2.5、0.25和0.0333秒。这些图像可以从Wikipedia下载。
import cv2 as cvimport numpy as np# 假设曝光图像文件名为img0.jpg、img1.jpg等img_fn = ["img0.jpg", "img1.jpg", "img2.jpg", "img3.jpg"]img_list = [cv.imread(fn) for fn in img_fn]exposure_times = np.array([15.0, 2.5, 0.25, 0.0333], dtype=np.float32)
cv.createMergeDebevec()和cv.createMergeRobertson()。这两种方法适用于不同的场景。# Debevec 合成merge_debevec = cv.createMergeDebevec()hdr_debevec = merge_debevec.process(img_list, times=exposure_times.copy())# Robertson 合成merge_robertson = cv.createMergeRobertson()hdr_robertson = merge_robertson.process(img_list, times=exposure_times.copy())
# 色调图映射tonemap1 = cv.createTonemap(gamma=2.2)res_debevec = tonemap1.process(hdr_debevec.copy())
# Mertens 融合merge_mertens = cv.createMergeMertens()res_mertens = merge_mertens.process(img_list)
# 转为8位并保存def convert_to_uint8(image): return np.clip(image * 255, 0, 255).astype('uint8')# Debevec 结果res_debevec_8bit = convert_to_uint8(res_debevec)cv.imwrite("ldr_debevec.jpg", res_debevec_8bit)# Robertson 结果res_robertson_8bit = convert_to_uint8(res_robertson)cv.imwrite("ldr_robertson.jpg", res_robertson_8bit)# Mertens 结果res_mertens_8bit = convert_to_uint8(res_mertens)cv.imwrite("fusion_mertens.jpg", res_mertens_8bit) CRF是HDR算法的重要组成部分,它描述了相机在不同曝光时间下的响应特性。OpenCV提供了两种方法来估计CRF:cv.createCalibrateDebevec()和cv.createCalibrateRobertson()。
# 估计 CRF 并生成 HDR 图像cal_debevec = cv.createCalibrateDebevec()crf_debevec = cal_debevec.process(img_list, times=exposure_times)hdr_debevec = merge_debevec.process(img_list, times=exposure_times.copy(), response=crf_debevec.copy())cal_robertson = cv.createCalibrateRobertson()crf_robertson = cal_robertson.process(img_list, times=exposure_times)hdr_robertson = merge_robertson.process(img_list, times=exposure_times.copy(), response=crf_robertson.copy())
如需了解更多OpenCV-Python教程,请关注我们的专栏或扫描二维码加入交流群。
转载地址:http://reav.baihongyu.com/