前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >OpenCV高动态范围成像(HDR)介绍与使用

OpenCV高动态范围成像(HDR)介绍与使用

作者头像
Color Space
发布2021-11-04 17:08:29
9960
发布2021-11-04 17:08:29
举报
文章被收录于专栏:OpenCV与AI深度学习

点击下方卡片,关注“OpenCV与AI深度学习

视觉/图像重磅干货,第一时间送达

来源:OpenCV4.5.4官方文档

翻译整理:Color Space

背景介绍

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

获取 HDR 图像的方法有多种,但最常见的一种是使用不同曝光值拍摄的场景照片。要结合这些曝光,了解相机的响应函数很有用,并且有算法可以对其进行估计。混合 HDR 图像后,必须将其转换回 8 位才能在通常的显示器上查看。这个过程称为色调映射。当场景或相机的对象在镜头之间移动时会出现额外的复杂性,因为应该注册和对齐具有不同曝光度的图像。

在本教程中,我们将展示如何从曝光序列生成和显示 HDR 图像。在我们的例子中,图像已经对齐并且没有移动的物体。我们还展示了一种称为曝光融合的替代方法,该方法可生成低动态范围图像。HDR 流水线的每一步都可以使用不同的算法来实现,因此请查看参考手册以查看全部内容。

曝光顺序

源代码

代码语言:javascript
复制
#include "opencv2/photo.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
#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 | | Input directory that contains images and exposure times. }" );
    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();
}

示例图像

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

解释说明

  • 加载图像和曝光时间
代码语言:javascript
复制
vector<Mat> images;
vector<float> times;
loadExposureSeq(parser.get<String>( "@input" ), images, times);

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

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

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

很多HDR构建算法都需要了解相机响应函数(CRF)。我们使用其中一种校准算法来估计所有 256 个像素值的逆 CRF。

  • 制作 HDR 图像
代码语言:javascript
复制
Mat hdr;
Ptr<MergeDebevec> merge_debevec = createMergeDebevec();
merge_debevec->process(images, hdr, times, response);

我们使用 Debevec 的加权方案使用在上一项中计算的响应来构建 HDR 图像。

  • 色调映射 HDR 图像
代码语言:javascript
复制
Mat ldr;
Ptr<Tonemap> tonemap = createTonemap(2.2f);
tonemap->process(hdr, ldr);

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

  • 执行曝光融合
代码语言:javascript
复制
Mat fusion;
Ptr<MergeMertens> merge_mertens = createMergeMertens();
merge_mertens->process(images, fusion);

当我们不需要 HDR 图像时,有一种替代方法可以合并我们的曝光。此过程称为曝光融合,可生成不需要伽马校正的 LDR 图像。它也不使用照片的曝光值。

  • 写入结果
代码语言:javascript
复制
imwrite ( "fusion.png" , fusion * 255);
imwrite ( "ldr.png" , ldr * 255);
imwrite ( "hdr.hdr" , hdr);

现在是时候看看结果了。请注意,HDR 图像不能以一种常见的图像格式存储,因此我们将其保存为 Radiance 图像 (.hdr)。此外,所有 HDR 成像函数都返回 [0, 1] 范围内的结果,因此我们应该将结果乘以 255。

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

结果

  • 色调映射图像

  • 曝光融合
  • 参考链接: https://docs.opencv.org/4.5.4/d3/db7/tutorial_hdr_imaging.html https://blog.csdn.net/LuohenYJ/article/details/89712234

—版权声明—

仅用于学术分享,版权属于原作者。

如有侵权,请联系微信号:Color_Space_001 删除或修改!

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-10-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 OpenCV与AI深度学习 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 背景介绍
    • 曝光顺序
      • 源代码
        • 示例图像
          • 解释说明
            • 结果
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档