OpenCV Module 10: HDR Imaging
High Dynamic Range (HDR) Imaging
Step 1: Capture Multiple Exposures
import cv2
import numpy as np
import matplotlib.pyplot as plt
def readImagesAndTimes():
#List of file names
filenames = ["img_0.033.jpg", "img_0.25.jpg", "img_2.5.jpg", "img_15.jpg"]
#List of exposure times
times = np.array([ 1/30.0, 0.35, 2.5, 15.0 ], dtype=np.float32)
#Read images
images = []
for filename in filenames:
im = cv2.imread(filename)
im = cv2.cvtColor(im, cv2.COLOR_BGR2RGB)
images.append(im)
return images, times
Step 2: Align Images
» Some ghost artifacts are introduced in the process and must be aligned
#Read images and exposure times
images, times = readImagesAndTimes()
#Align Images
alignMTB = cv2.createAlignMTB()
alignMTB.process(images, images)
Step 3: Estimate Camera Response Function
#Find Camera Response Function (CRF)
calibrateDebevec = cv2.createCalibrateDebevec()
responseDebevec = calibrateDebevec.process(images, times)
#Plot CRF
x = np.arange(256, dtype=np.uint8)
y = np.squeeze(responseDebevec)
ax = plt.figure(figsize=(30,10))
plt.title("Debevec Inverse Camera Response Function", fontsize=24)
plt.xlabel("Measured Pixel Value", fontsize=22)
plt.ylabel("Calibrated Intensity", fontsize=22)
plt.xlim([0,260])
plt.grid()
plt.plot(xm y[:,0], 'r', x, y[:,1], 'g', x, y[:,2], 'b');
Step 4: Merge Exposure into an HDR Image
#Merge images into an HDR linear image
mergeDebevec = cv2.createMergeDebevec()
hdrDebevec = mergeDebevec.process(images, times, responseDebevec)
Step 5: Tonemapping
» Using Durand Tonemapping algorithm
#Tonemap using Drago's method to obtain 24-bit color image
tonemapDrago = cv2.createTonemapDrago(1.0, 0.7)
ldrDrago = tonemapDrago.process(hdrDebevec)
ldrDrago = 3 * ldrDrago
plt.figure(figsize=(20,10)); plt.imshow(np.clip(ldrDrago,0,1)); plt.axis('off');
cv2.imwrite("ldr-Drago.jpg", ldrDrago * 255)
print("saved ldr-Drago.jpg")
» Check other Tonemapping algorithms