import cv2
import numpy as np
def readImagesAndTimes(): # 曝光时间列表
times = np.array([ 1/30.0, 0.25, 2.5, 15.0 ], dtype=np.float32) # 图像文件名称列表
filenames = ["img_0.033.jpg", "img_0.25.jpg", "img_2.5.jpg", "img_15.jpg"]
images = []
for filename in filenames:
im = cv2.imread(filename)
images.append(im)
return images, times
# 对齐输入图像
alignMTB = cv2.createAlignMTB()
alignMTB.process(images, images)
# 获取图像响应函数 (CRF)
calibrateDebevec = cv2.createCalibrateDebevec()
responseDebevec = calibrateDebevec.process(images, times)
# 将图像合并为HDR线性图像
mergeDebevec = cv2.createMergeDebevec()
hdrDebevec = mergeDebevec.process(images, times, responseDebevec)
# 保存图像
cv2.imwrite("hdrDebevec.hdr", hdrDebevec)
色调映射
有好几种方法,首先有以下几个概念
伽马gamma:
该参数通过应用伽马校正来压缩动态范围。 当伽马等于 1 时,不应用修正。 小于 1 的伽玛会使图像变暗,而大于 1 的伽马会使图像变亮。
像素归一化与0到1之间
上一部结果的gamma分之1次方
反归一化,是上一部的结果乘以256,减去0.5
对比度:
是一个亮度的比值,定义是:在暗室中,白色画面(最亮时)下的亮度除以黑色画面(最暗时)下的亮度。更精准地说,对比度就是把白色信号在100%和0%的饱和度相减,再除以用Lux(光照度,即勒克斯,每平方米的流明值)为计量单位下0%的白色值(0%的白色信号实际上就是黑色),所得到的数值。对比度是最黑与最白亮度单位的相除值。
饱和度
是指色彩的鲜艳程度,也称色彩的纯度。饱和度取决于该色中含色成分和消色成分(灰色)的比例。含色成分越大,饱和度越大;消色成分越大,饱和度越小。
Drago映射,即自适应对数映射
论文链接
# 使用Drago色调映射算法获得24位彩色图像tonemapDrago = cv2.createTonemapDrago(1.0, 0.7)
ldrDrago = tonemapDrago.process(hdrDebevec)
ldrDrago = 3 * ldrDrago
cv2.imwrite("ldr-Drago.jpg", ldrDrago * 255)
# 使用Durand色调映射算法获得24位彩色图像
tonemapDurand = cv2.createTonemapDurand(1.5,4,1.0,1,1)
ldrDurand = tonemapDurand.process(hdrDebevec)
ldrDurand = 3 * ldrDurand
cv2.imwrite("ldr-Durand.jpg", ldrDurand * 255)
# 使用Reinhard色调映射算法获得24位彩色图像
tonemapReinhard = cv2.createTonemapReinhard(1.5, 0,0,0)
ldrReinhard = tonemapReinhard.process(hdrDebevec)
cv2.imwrite("ldr-Reinhard.jpg", ldrReinhard * 255)
# 使用Mantiuk色调映射算法获得24位彩色图像tonemapMantiuk = cv2.createTonemapMantiuk(2.2,0.85, 1.2)
ldrMantiuk = tonemapMantiuk.process(hdrDebevec)
ldrMantiuk = 3 * ldrMantiuk
cv2.imwrite("ldr-Mantiuk.jpg", ldrMantiuk * 255)
论文作者:Tom Mertens
高斯金字塔:高斯金字塔是最基本的图像塔。首先将原图像作为最底层图像G0(高斯金字塔的第0层),利用高斯核(5*5)对其进行卷积,然后对卷积后的图像进行下采样(去除偶数行和列)得到上一层图像G1,将此图像作为输入,重复卷积和下采样操作得到更上一层图像,反复迭代多次,形成一个金字塔形的图像数据结构,即高斯金字塔。
拉普拉斯金字塔:在高斯金字塔的运算过程中,图像经过卷积和下采样操作会丢失部分高频细节信息。为描述这些高频信息,人们定义了拉普拉斯金字塔(Laplacian Pyramid, LP)。用高斯金字塔的每一层图像减去其上一层图像上采样并高斯卷积之后的预测图像,得到一系列的差值图像即为 LP 分解图像。
以下代码基于matlab:
%构建高斯金字塔
function pyr = gaussian_pyramid(I,nlev)
r = size(I,1);
c = size(I,2);
if ~exist('nlev')
nlev = floor(log(min(r,c)) / log(2));
end
pyr = cell(nlev,1);
pyr{1} = I;
filter = pyramid_filter;
for l = 2:nlev
I = downsample(I,filter);
pyr{l} = I;
end
%构建拉普拉斯金字塔
function pyr = laplacian_pyramid(I,nlev)
r = size(I,1);
c = size(I,2);
if ~exist('nlev')
nlev = floor(log(min(r,c)) / log(2));
end
pyr = cell(nlev,1);
filter = pyramid_filter;
J = I;
for l = 1:nlev - 1
I = downsample(J,filter);
odd = 2*size(I) - size(J); % for each dimension, check if the upsampled version has to be odd
pyr{l} = J - upsample(I,odd,filter);
J = I;
end
pyr{nlev} = J;
% contrast measure
function C = contrast(I)
h = [0 1 0; 1 -4 1; 0 1 0]; % laplacian filter
N = size(I,4);
C = zeros(size(I,1),size(I,2),N);
for i = 1:N
mono = rgb2gray(I(:,:,:,i));
C(:,:,i) = abs(imfilter(mono,h,'replicate'));
end
% saturation measure
function C = saturation(I)
N = size(I,4);
C = zeros(size(I,1),size(I,2),N);
for i = 1:N
% saturation is computed as the standard deviation of the color channels
R = I(:,:,1,i);
G = I(:,:,2,i);
B = I(:,:,3,i);
mu = (R + G + B)/3;
C(:,:,i) = sqrt(((R - mu).^2 + (G - mu).^2 + (B - mu).^2)/3);
end
% well-exposedness measure
function C = well_exposedness(I)
sig = .2;
N = size(I,4);
C = zeros(size(I,1),size(I,2),N);
for i = 1:N
R = exp(-.5*(I(:,:,1,i) - .5).^2/sig.^2);
G = exp(-.5*(I(:,:,2,i) - .5).^2/sig.^2);
B = exp(-.5*(I(:,:,3,i) - .5).^2/sig.^2);
C(:,:,i) = R.*G.*B;
end