OpenCV Computational Photography 计算摄影

HDR (High Dynamic Range) 高动态范围图像

手机一直开着自动HDR,但是其实不知道它究竟是用来干啥的,也没看出效果究竟在哪(好像只是图像变清晰了😅),上完这节课终于明白了

现在我们的数字彩色图像一般是用24位存储颜色矩阵的,也就是R,G,B各8-bit,但现实中的色域远远不止0-255,所以过亮/过暗的区域在图像中总是不能很好地显示.

HDR的工作原理是:

采集多张不同曝光的图像->HDR->8-bit图像**

实现HDR有很多种方法,如Devebec’s,Robertson’s Method 等,还可以使用曝光融合(exposure fusion, mertens, …)

实践HDR

具体步骤

  1. 采集多张图像

    最少3张: underexposed, properly image, overexposed

  2. 校准图像

  3. 计算图像响应函数

    由于多张图像采用了不同的曝光时间,故得到图像的值也不同,但是这个值与曝光时间并不是线性关系的,所以我们需要估计Camera Response Function (CRF),才能融合图像

  4. 图像融合

    得到HDR图像

  5. 将HDR存为8-bit图像

以上步骤参考了:

https://www.learnopencv.com/high-dynamic-range-hdr-imaging-using-opencv-cpp-python/

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#! /usr/local/bin/python
# -*- coding: UTF-8 -*-
import cv2
import numpy as np

# times = times = np.array([ 1/30.0, 0.25, 2.5, 15.0 ], dtype=np.float32)# 曝光时间
# filenames = ["HDR/images/hdr-image-sequence_01.png", "HDR/images/hdr-image-sequence_02.png", "HDR/images/hdr-image-sequence_03.png", "HDR/images/hdr-image-sequence_04.png"]
times = np.array([ 1/30.0, 1/4.0, 1.0, 2.5, 4.0, 8.0, 16.0 ], dtype=np.float32)# 曝光时间
filenames = ["HDR/1.png", "HDR/2.png", "HDR/3.png", "HDR/4.png", "HDR/5.png", "HDR/6.png", "HDR/7.png",]
images = []# 存所有图像
for i in range(len(filenames)):
img = cv2.imread(filenames[i])
cv2.imshow("Original "+str(i),img)# 显示图像
images.append(img)

alignMTB = cv2.createAlignMTB()# OpenCV提供的图像校准工具 # <AlignMTB 0x100a7c810>
print(alignMTB)
aligned_images = []
alignMTB.process(images, aligned_images) # 生成aligned images
# for i in range(len(aligned_images)):
# cv2.imshow("aligned_images "+str(i),aligned_images[i])# 显示图像
print(aligned_images)# []
calibrateDebevec = cv2.createCalibrateDebevec()# 确定图像响应函数CRF # <CalibrateDebevec 0x100a7c7b0>
# print(calibrateDebevec)
responseDebevec = calibrateDebevec.process(images, times)# 根据曝光时间估算
# print(responseDebevec)

mergeDebevec = cv2.createMergeDebevec()# 合成矩阵
hdrDebevec = mergeDebevec.process(images, times, responseDebevec)# 合成HDR
cv2.imwrite("hdrDebevec.hdr", hdrDebevec)# 保存HDR图像
cv2.imshow("HDR Image",hdrDebevec)
cv2.waitKey(0) #关闭窗口/键盘ESC退出
cv2.destroyAllWindows()

注意:

  1. 输入的7张原始图像需要是相同大小的,老师给的图像大小不一致,所以需要在photoshop中修改一下
  2. 曝光时间矩阵需要float32类型的,所以在整数后加.0,否则不会存为浮点数

结果

原始图像:

0

1

2

3

4

5

6

HDR图像:

HDR

可以看到取得了较好的效果

0%