OpenCV  4.10.0
开源计算机视觉
正在加载...
正在搜索...
无匹配项
高动态范围 (HDR)

目标

在本节中,我们将

  • 学习如何从曝光序列生成和显示 HDR 图像。
  • 使用曝光融合来合并曝光序列。

理论

高动态范围成像 (HDRI 或 HDR) 是一种用于成像和摄影的技术,用于再现比标准数字成像或摄影技术所能达到的更大的亮度动态范围。虽然人眼可以适应各种光线条件,但大多数成像设备使用每通道 8 位,因此我们仅限于 256 个级别。当我们拍摄真实世界场景的照片时,明亮区域可能会过度曝光,而黑暗区域可能会曝光不足,因此我们无法使用单次曝光捕捉所有细节。HDR 成像使用每通道超过 8 位的图像(通常为 32 位浮点数),允许更大的动态范围。

获得 HDR 图像的方法有很多,但最常见的方法是使用以不同曝光值拍摄的场景照片。为了组合这些曝光,了解相机的响应函数很有用,并且存在用于估计它的算法。在合并 HDR 图像后,必须将其转换回 8 位才能在普通显示器上查看。此过程称为色调映射。当场景中的物体或相机在拍摄之间移动时,会产生额外的复杂性,因为具有不同曝光值的图像应该被配准和对齐。

在本教程中,我们展示了两种算法(Debevec、Robertson)来从曝光序列生成和显示 HDR 图像,并展示了一种称为曝光融合(Mertens)的替代方法,该方法生成低动态范围图像并且不需要曝光时间数据。此外,我们估计了相机响应函数 (CRF),它对于许多计算机视觉算法具有重要价值。HDR 管道的每个步骤都可以使用不同的算法和参数实现,因此请查看参考手册以查看所有参数。

曝光序列 HDR

在本教程中,我们将关注以下场景,我们有 4 张曝光图像,曝光时间分别为:15 秒、2.5 秒、1/4 秒和 1/30 秒。(您可以从 维基百科 下载这些图像)

图像

1. 将曝光图像加载到列表中

第一步是简单地将所有图像加载到列表中。此外,对于常规 HDR 算法,我们将需要曝光时间。注意数据类型,因为图像应为 1 通道或 3 通道 8 位(np.uint8),曝光时间需要为 float32 并以秒为单位。

import cv2 as cv
import numpy as np
# 将曝光图像加载到列表中
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_EXPORTS_W Mat imread(const String &filename, int flags=IMREAD_COLOR)
从文件加载图像。

2. 将曝光合并到 HDR 图像中

在此步骤中,我们将曝光序列合并为一个 HDR 图像,展示了 OpenCV 中的两种可能性。第一种方法是 Debevec,第二种方法是 Robertson。注意,HDR 图像的类型为 float32,而不是 uint8,因为它包含所有曝光图像的完整动态范围。

# 将曝光合并到 HDR 图像中
merge_debevec = cv.createMergeDebevec()
hdr_debevec = merge_debevec.process(img_list, times=exposure_times.copy())
merge_robertson = cv.createMergeRobertson()
hdr_robertson = merge_robertson.process(img_list, times=exposure_times.copy())
Ptr< MergeDebevec > createMergeDebevec()
创建 MergeDebevec 对象。
Ptr< MergeRobertson > createMergeRobertson()
创建 MergeRobertson 对象。

3. 色调映射 HDR 图像

我们将 32 位浮点数 HDR 数据映射到 [0..1] 范围。实际上,在某些情况下,值可能大于 1 或小于 0,因此请注意,我们稍后将必须剪切数据以避免溢出。

# 色调映射 HDR 图像
tonemap1 = cv.createTonemap(gamma=2.2)
res_debevec = tonemap1.process(hdr_debevec.copy())
Ptr< Tonemap > createTonemap(float gamma=1.0f)
创建具有伽马校正的简单线性映射器。

4. 使用 Mertens 融合合并曝光

这里我们展示了一种合并曝光图像的替代算法,我们不需要曝光时间。我们也不需要使用任何色调映射算法,因为 Mertens 算法已经为我们提供了 [0..1] 范围内的结果。

# 使用 Mertens 进行曝光融合
merge_mertens = cv.createMergeMertens()
res_mertens = merge_mertens.process(img_list)
Ptr< MergeMertens > createMergeMertens(float contrast_weight=1.0f, float saturation_weight=1.0f, float exposure_weight=0.0f)
创建 MergeMertens 对象。

5. 转换为 8 位并保存

为了保存或显示结果,我们需要将数据转换为 [0..255] 范围内的 8 位整数。

# 将数据类型转换为 8 位并保存
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')
cv.imwrite("ldr_debevec.jpg", res_debevec_8bit)
cv.imwrite("ldr_robertson.jpg", res_robertson_8bit)
cv.imwrite("fusion_mertens.jpg", res_mertens_8bit)
CV_EXPORTS_W bool imwrite(const String &filename, InputArray img, const std::vector< int > &params=std::vector< int >())
将图像保存到指定文件。

结果

您可以看到不同的结果,但请注意,每种算法都有额外的参数,您应该调整这些参数以获得所需的输出。最佳做法是尝试不同的方法,看看哪种方法最适合您的场景。

Debevec

图像

Robertson

图像

Mertenes 融合

图像

估计相机响应函数

相机响应函数 (CRF) 为我们提供了场景辐射与测量强度值之间联系。CRF 在某些计算机视觉算法(包括 HDR 算法)中非常重要。这里我们估计逆相机响应函数并将其用于 HDR 合并。

# 估计相机响应函数 (CRF)
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())
Ptr< CalibrateRobertson > createCalibrateRobertson(int max_iter=30, float threshold=0.01f)
创建 CalibrateRobertson 对象。
Ptr< CalibrateDebevec > createCalibrateDebevec(int samples=70, float lambda=10.0f, bool random=false)
创建 CalibrateDebevec 对象。

相机响应函数由每个颜色通道的 256 个长度的向量表示。对于此序列,我们获得了以下估计

图像

附加资源

  1. Paul E Debevec 和 Jitendra Malik。从照片中恢复高动态范围辐射图。在 ACM SIGGRAPH 2008 类别中,第 31 页。ACM,2008。 [68]
  2. Mark A Robertson、Sean Borman 和 Robert L Stevenson。通过多次曝光改善动态范围。在 1999 年图像处理中。ICIP 99。论文集。1999 年国际图像处理会议,第 3 卷,第 159-163 页。IEEE,1999。 [226]
  3. Tom Mertens、Jan Kautz 和 Frank Van Reeth。曝光融合。在 2007 年计算机图形和应用程序中。PG'07。第 15 届太平洋计算机图形会议,第 382-390 页。IEEE,2007。 [188]
  4. 来自 维基百科-HDR 的图像

练习

  1. 尝试所有色调映射算法: cv::TonemapDragocv::TonemapMantiukcv::TonemapReinhard
  2. 尝试更改 HDR 校准和色调映射方法中的参数。