HDR(High Dynamic Range)多曝光融合是从一组在同一场景下不同曝光设置下拍摄的图像中合成一张高动态范围图像。单次曝光的照片往往无法捕捉到场景中同时存在的明亮区域和阴暗区域的全部细节,而多曝光融合则可以综合这些不同曝光等级照片中的优势信息,使得合成出来的图像拥有更广的动态范围和更多的细节层次。以下是采用“曝光融合”方法的Python实现。
import cv2
import numpy as np
import glob
获取同一场景下不同曝光的图像列表(替换自己的文件路径)
image_paths = sorted(glob.glob(r'C:\Users\csdn\Desktop\images\*.png'))
示例
定义一个统一的目标尺寸
target_height, target_width = cv2.imread(image_paths[0]).shape[:2]
加载图像、调整尺寸并转换为统一的3通道格式
images_rgb = []
for img_path in image_paths:
img = cv2.imread(img_path, -1).astype(np.float32)
img_resized = cv2.resize(img, (target_width, target_height))
# 转换为3通道图像
if img.shape[2] == 4: # 处理4通道(RGBA)图像
img_rgb = cv2.cvtColor(img_resized, cv2.COLOR_RGBA2RGB)
elif img.shape[2] == 3: # 保留3通道(RGB)图像
img_rgb = img_resized
elif img.shape[2] == 1: # 如果是灰度图,转为RGB格式
img_rgb = cv2.cvtColor(img_resized, cv2.COLOR_GRAY2RGB)
else:
raise ValueError(f"无法处理{img.shape[2]}通道的图像")
images_rgb.append(img_rgb)
将所有图像尺寸转换一致
assert len(set([img.shape[:2] for img in images_rgb])) == 1, "所有图像尺寸应当相同"
将所有图像统一为3通道图像
assert all([img.shape[2] == 3 for img in images_rgb]), "所有图像必须是三通道(RGB彩色)"
创建并执行HDR融合方法
merge_method = cv2.createMergeMertens()
hdr_image = merge_method.process(images_rgb)
对HDR图像进行线性拉伸以适应显示器的显示能力,并将其转换为8位整数类型的LDR(Low Dynamic Range)图像以便于显示和保存。(需要色调映射)
max_value = hdr_image.max()
ldr_image = hdr_image / max_value * 255.0
ldr_image = np.clip(ldr_image, 0, 255).astype(np.uint8)
保存LDR图像
cv2.imwrite('hdr_output_ldr.png', ldr_image * 255.0)
显示LDR图像
cv2.imshow("LDR Image", ldr_image.astype(np.uint8))
cv2.waitKey(0)
cv2.destroyAllWindows()
HDR处理效果图