Opencv实验合集——实验五:高动态范围
1.概念
高动态范围成像(HDRI 或 HDR)是一种用于成像和摄影的技术,可以再现比标准数字成像或照相技术更大的动态光度范围。虽然人眼可以适应各种光线条件,但大多数成像设备每通道使用 8 位,因此我们仅限于 256 级。当我们拍摄现实世界场景的照片时,明亮区域可能会过度曝光,而暗区域可能曝光不足,因此我们无法使用单次曝光捕捉所有细节。 HDR 成像适用于每通道使用 8 位以上(通常为 32 位浮点值)的图像,从而允许更宽的动态范围。
获得 HDR 图像的方法有很多种,但最常见的方法是使用不同曝光值拍摄的场景照片。要结合这些曝光,了解相机的响应函数是有用的,并且有估算它的算法。合并 HDR 图像后,必须将其转换回 8 位以在通常的显示器上查看。此过程称为色调映射。当场景或相机的物体在镜头之间移动时会出现额外的复杂性,因为应该注册和对齐具有不同曝光的图像。
在本教程中,我们展示了 2 种算法(Debevec,Robertson),用于从曝光序列生成和显示 HDR 图像,并演示了一种称为曝光融合(Mertens)的替代方法,该方法产生低动态范围图像,不需要曝光时间数据。此外,我们估计相机响应函数(CRF),这对许多计算机视觉算法具有重要价值。
首先简单了解一下什么是HDR图像和LDR图像
?HDR(High Dynamic Range)图像是一种能够捕捉和表示比标准图像(LDR,Low Dynamic Range)更广泛亮度范围的图像。HDR 图像可以包含来自不同曝光的多个图像,以便在亮度较低和较高的区域都能保留细节。
LDR(Low Dynamic Range)图像是一种在亮度范围上有限的图像,通常表示为每个像素的颜色值在一个相对较小的范围内,例如0到255。与HDR图像相比,LDR图像的主要特点是亮度范围较窄。
总的来说,HDR图像是专业化图像,具备类似曝光时间,曝光度等指标,LDR图像是日常实验或看到的图像,0-255像素,HDR就类似于高级摄像机拍东西,LDR就类似于普通手机拍东西
2.有关的函数方法
1.将曝光序列合并成一个HDR图像
cv2.createMergeDebevec()
是 OpenCV 中用于创建 Debevec 曝光融合器的函数。这个函数返回一个 cv2.MergeDebevec
对象。Debevec 曝光融合是一种用于生成高动态范围(HDR)图像的技术,通过合并拥有不同曝光时间的图像来捕获大范围的亮度信息。
cv2.createMergeRobertson()
是 OpenCV 中用于创建 Robertson 曝光融合器的函数。这个函数返回一个 cv2.MergeRobertson
对象。Robertson 曝光融合是一种用于生成高动态范围(HDR)图像的技术,类似于Debevec方法,但在考虑噪声方面表现更好。
2.范围映射
cv2.createTonemap
用于创建一个色调映射器(Tonemap),该映射器被用于将高动态范围(HDR)图像映射到低动态范围(LDR)图像。
tonemap.process
方法然后将 HDR 图像应用于该映射器,生成一个 LDR 图像。
cv2.createTonemap(gamma)
: 创建一个色调映射器对象。gamma
参数指定了伽马值,用于调整图像的对比度。伽马值越大,对比度越低,图像越亮。
tonemap.process(hdr)
: 将 HDR 图像 hdr
应用到色调映射器上。这一步将 HDR 图像转换为 LDR 图像,以便在标准显示器上显示。在这个过程中,色调映射器可以执行一些算法来调整图像的亮度、对比度和颜色饱和度等,以在 LDR 显示上获得更好的效果。
3.Mertens 曝光融合
Mertens 曝光融合是一种用于生成高动态范围(HDR)图像的技术,通过合并拥有不同曝光时间的图像来捕获大范围的亮度信息。这种方法的优势之一是在融合时采用了对比度增强的方法,以生成自然外观的HDR图像。
而且是一种合并曝光图像的替代算法,我们不需要曝光时间。我们也不需要使用任何色调图算法,因为 Mertens 算法已经给出了[0..1]范围内的结果。
示例代码:
import cv2
import numpy as np
# Loading exposure images into a list
img_fn = [r"C:\Users\xiaoou\Desktop\picture/sun1.jpg", r"C:\Users\xiaoou\Desktop\picture/sun2.jpg", r"C:\Users\xiaoou\Desktop\picture/sun3.jpg"]
img_list = [cv2.imread(fn) for fn in img_fn]
img_list = [cv2.resize(img,(500,500)) for img in img_list]
exposure_times = np.array([1,0.3,0.012], dtype=np.float32)#设置曝光时间
imagemerge_debevec = cv2.createMergeDebevec()
hdr_debevec = imagemerge_debevec.process(img_list, times=exposure_times.copy())#处理对应的图片和曝光时间
merge_robertson = cv2.createMergeRobertson()
hdr_robertson = merge_robertson.process(img_list, times=exposure_times.copy())
tonemap1 = cv2.createTonemap(gamma=5.6)
res_debevec = tonemap1.process(hdr_debevec.copy())
tonemap2 = cv2.createTonemap(gamma=4.6)
res_robertson = tonemap2.process(hdr_robertson.copy())
merge_mertens = cv2.createMergeMertens()#简化了很多条件,在未知图片曝光时间的情况下可以使用
res_mertens = merge_mertens.process(img_list)
# Convert datatype to 8-bit and save
res_debevec_8bit = np.clip(res_debevec*255, 0, 255).astype('uint8')#将浮点数转化为0-255的数,这样就变成LDR,可以实现展示
res_robertson_8bit = np.clip(res_robertson*255, 0, 255).astype('uint8')
res_mertens_8bit = np.clip(res_mertens*255, 0, 255).astype('uint8')
cv2.imshow('res_debevec_8bit', res_debevec_8bit)
cv2.imshow('res_robertson_8bit', res_robertson_8bit)
cv2.imshow('res_mertens_8bit', res_mertens_8bit)
cv2.waitKey(0)
效果展示:
原图:
结果图:
德普外阁(Debevec):
罗伯逊(Robertson):
?
梅特内斯·福森(Mertenes Fusion):
本次实验主要展示了计算摄影中的高动态范围,主要任务还是将不同曝光度的照片进行一个结合,本次小编实验的图片是小编自己拍摄的,所以忘记了曝光时间,通过假定设置去进行实验,但是还是因为曝光时间设置不好的问题,还是觉得最后一个?Mertenes 方法更自然更好看一点。
详情了解高动态范围 - 维基百科,自由的百科全书 (wikipedia.org)
如有错误或遗漏,希望小伙伴批评指正!!!!?
希望这篇博客对你有帮助!!!!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!