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

下一篇教程: 高级拼接 API(Stitcher 类)

原始作者费多尔·莫罗佐夫
兼容性OpenCV >= 3.0

简介

目前大多数数字图像和成像设备每通道使用 8 位,从而将设备的动态范围限制在两个数量级(实际上是 256 个级别),而人眼可以适应亮度条件的变化,变化幅度达十个数量级。当我们拍摄真实场景的照片时,明亮区域可能会曝光过度,而较暗区域可能会曝光不足,因此无法使用单次曝光捕捉所有细节。HDR 成像处理每通道使用超过 8 位(通常为 32 位浮点值)的图像,从而允许更大的动态范围。

获取 HDR 图像的方法有很多,但最常见的方法是使用以不同的曝光值拍摄的场景照片。要合并这些曝光,了解相机的响应函数非常有用,并且有用于估计响应函数的算法。将 HDR 图像混合后,必须将其转换回 8 位才能在常规显示器上查看。此过程称为色调映射。当场景中的物体或相机在拍摄中移动时,则会出现其他复杂的情况,因为不同曝光的图像应被配准并对齐。

在本教程中,我们将展示如何从曝光序列中生成和显示 HDR 图像。在我们的案例中,图像已经对齐并且没有移动的物体。我们还演示了一种称为曝光融合的备用方法,该方法会生成低动态范围图像。HDR 管道的每个步骤都可以使用不同的算法实现,因此可以查看参考手册以查看所有算法。

曝光序列

源代码

本教程代码已显示在以下行中。您还可以从 此处 下载代码

#include <vector>
#include <iostream>
#include <fstream>
using namespace cv;
using namespace std;
void loadExposureSeq(String, vector<Mat>&, vector<float>&);
int main(int argc, char**argv)
{
CommandLineParser parser( argc, argv, "{@input | | 输入目录,其中包含图像和曝光时间。 }" );
vector<Mat> images;
vector<float> times;
loadExposureSeq(parser.get<String>( "@input" ), images, times);
Mat response;
Ptr<CalibrateDebevec> calibrate = createCalibrateDebevec();
calibrate->process(images, response, times);
Mat hdr;
Ptr<MergeDebevec> merge_debevec = createMergeDebevec();
merge_debevec->process(images, hdr, times, response);
Mat ldr;
Ptr<Tonemap> tonemap = createTonemap(2.2f);
tonemap->process(hdr, ldr);
Mat fusion;
Ptr<MergeMertens> merge_mertens = createMergeMertens();
merge_mertens->process(images, fusion);
imwrite("fusion.png", fusion * 255);
imwrite("ldr.png", ldr * 255);
imwrite("hdr.hdr", hdr);
return 0;
}
void loadExposureSeq(String path, vector<Mat>& images, vector<float>& times)
{
path = path + "/";
ifstream list_file((path + "list.txt").c_str());
string name;
float val;
while(list_file >> name >> val) {
Mat img = imread(path + name);
images.push_back(img);
times.push_back(1 / val);
}
list_file.close();
}
设计用于命令行解析。
定义 utility.hpp:820
n 维稠密数组类
定义 mat.hpp:812
std::string String
定义 cvstd.hpp:151
std::shared_ptr< _Tp > Ptr
定义 cvstd_wrapper.hpp:23
int main(int argc, char *argv[])
定义 highgui_qt.cpp:3
与磁盘上的文件关联的文件存储的“黑盒”表示形式。
定义 core.hpp:102
STL 命名空间。

示例图

可以从 此处 下载包含图像、曝光时间和 list.txt 文件的数据目录。

说明

  • 加载图像和曝光时间
vector<Mat> images;
vector<float> times;
loadExposureSeq(parser.get<String>( "@input" ), images, times);

首先,我们要从用户定义的文件夹中加载输入图像和曝光时间。文件夹应包含图像和 list.txt 文件 - 该文件包含文件名和反曝光时间。

对于我们的图像序列,列表如下

memorial00.png 0.03125
memorial01.png 0.0625
...
memorial15.png 1024
  • 估计相机响应
Mat response;
Ptr<CalibrateDebevec> calibrate = createCalibrateDebevec();
calibrate->process(images, response, times);

对于很多 HDR 构造算法而言,要知道相机响应函数(CRF)是必要的。我们使用其中一种校准算法,为所有 256 像素值估计逆 CRF。

  • 制作 HDR 图像
Mat hdr;
Ptr<MergeDebevec> merge_debevec = createMergeDebevec();
merge_debevec->process(images, hdr, times, response);

我们在前一个条目中计算的响应基础上使用 Debevec 的加权方案来构建 HDR 图像。

  • 色调映射 HDR 图像
Mat ldr;
Ptr<Tonemap> tonemap = createTonemap(2.2f);
tonemap->process(hdr, ldr);

由于我们希望在普通 LDR 显示器上查看我们的结果,我们必须将我们的 HDR 图像映射到 8 位范围,以保留大部分细节。这是色调映射方法的主要目标。我们使用带有双边滤波的色调映射器,并将 2.2 设为伽马校正值。

  • 执行曝光融合
Mat fusion;
Ptr<MergeMertens> merge_mertens = createMergeMertens();
merge_mertens->process(images, fusion);

如果我们不需要 HDR 图像,则还有另一种方式来合并我们的曝光。此过程称为曝光融合,它生成不需要伽马校正的 LDR 图像。它也不使用照片的曝光值。

  • 写入结果
imwrite("fusion.png", fusion * 255);
imwrite("ldr.png", ldr * 255);
imwrite("hdr.hdr", hdr);

现在是查看结果的时候了。请注意,HDR 图像无法存储在常见图像格式之一中,所以我们将其保存到 Radiance 图像(.hdr)。此外,所有 HDR 成像功能都会返回 [0, 1] 范围的结果,所以我们应该将结果乘以 255。

您可以尝试其他色调映射算法:cv::TonemapDragocv::TonemapMantiukcv::TonemapReinhard 您还可以在 HDR 校准和色调映射方法中调整您自己的照片参数。

结果

色调映射图像

曝光融合

其他资源

  1. Paul E Debevec and Jitendra Malik. Recovering high dynamic range radiance maps from photographs. In ACM SIGGRAPH 2008 classes, page 31. ACM, 2008. [68]
  2. 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. [226]
  3. 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. [188]
  4. 维基百科-HDR
  5. 从照片中恢复高动态范围亮度图(网页)