一,简介
在多曝光融合方法一中,我们首先估算相机的响应函数(CRF)。接着,利用 cv2.createCalibrateDebevec() 方法,依据相机的CRF对多曝光图像进行融合理。这一过程最终通过映射将高动态范围的图像生成平常我们常用的0-255范围的图像从而实现多曝光融合。此外,本文还将介绍一种更为直接的多曝光融合方法,它利用OpenCV提供的现成封装功能来完成融合操作,简化了多曝光融合的步骤。
二,实现方案
要想直接实现多曝光融合,首先,我们将读取的图像数据封装成一个列表,接着,利用 cv2.createAlignMTB() 方法对这些图像进行对齐处理,确保它们在空间上匹配。最后,使用 cv2.createMergeMertens() 方法对已经对齐的图像进行融合,最终生成具有高动态范围的融合图像。
三,算法实现步骤
3.1 cv2.createAlignMTB() 图像对齐
cv2.createAlignMTB() 是 OpenCV 库中的一个函数,用于创建一个基于 Middlebury Timing Benchmark (MTB) 算法的图像对齐对象。该算法主要用于对一系列曝光不同的图像进行对齐处理,减少由于相机移动或场景中物体移动导致的图像间的位移,从而为后续的图像融合或其他处理步骤做好准备。这个对齐对象不需要用户手动设置参数,即可自动计算图像间的差异并调整它们的位置,使得输出的图像在空间上对齐。使用该对象时,通常通过调用其 process 方法来实际执行图像对齐操作。
使用方法:
# 创建一个对齐对象,用于对输入图像进行对齐
alignMTB = cv2.createAlignMTB()
# 对图像列表进行对齐处理,结果存储在同一个列表中
alignMTB.process(images, images)
3.2 cv2.createMergeMertens()图像融合
cv2.createMergeMertens() 是 OpenCV 库中的一个函数,用于创建一个基于 Mertens 等人提出的算法的图像融合对象。这个算法用于将多个不同曝光的图像合并成一个具有高动态范围的图像,目的是在阴影和高光区域都保持良好的细节。创建的对象能够计算输入图像的特征,如对比度和饱和度,并为每个像素分配权重,然后使用这些权重将图像融合在一起,产生一个视觉效果良好的输出图像。使用该对象时,通常通过调用其 process 方法来执行图像融合操作。这个方法不需要用户手动设置太多参数,使得曝光融合过程相对简单且高效。
使用方法:
# 创建一个合并对象,用于曝光融合
mergeMertens = cv2.createMergeMertens()
# 使用合并对象处理图像列表,得到曝光融合的结果
exposureFusion = mergeMertens.process(images)
四:整体代码实现
import cv2
import numpy as np
import sys
# 定义一个函数,用于读取一组图像文件
def readImagesAndTimes():
# 定义一个包含图像文件路径的列表
filenames = [
"F:\\learnopencv-master\\ExposureFusion\\images/memorial0061.jpg",
"F:\\learnopencv-master\\ExposureFusion\\images/memorial0065.jpg",
"F:\\learnopencv-master\\ExposureFusion\\images/memorial0070.jpg",
"F:\\learnopencv-master\\ExposureFusion\\images/memorial0075.jpg",
]
# 创建一个空列表,用于存储读取的图像
images = []
# 遍历文件名列表,读取每个图像,并将其添加到图像列表中
for filename in filenames:
im = cv2.imread(filename)
images.append(im)
# 返回包含所有读取图像的列表
return images
# 确保以下代码仅在脚本作为主程序运行时执行
if __name__ == '__main__':
# 调用函数,读取图像列表
images = readImagesAndTimes()
# 创建一个对齐对象,用于对输入图像进行对齐
alignMTB = cv2.createAlignMTB()
# 对图像列表进行对齐处理,结果存储在同一个列表中
alignMTB.process(images, images)
# 创建一个合并对象,用于曝光融合
mergeMertens = cv2.createMergeMertens()
# 使用合并对象处理图像列表,得到曝光融合的结果
exposureFusion = mergeMertens.process(images)
# 打印消息,表示开始保存输出图像
print("Saving output ... exposure-fusion.jpg")
# 将曝光融合后的结果保存为图像文件,乘以255是为了将数据范围从[0,1]转换为[0,255]
cv2.imwrite("exposure-fusion.jpg", exposureFusion * 255)
五:效果
融合前的图片:
融合后的图像: