91 lines
2.6 KiB
Python
91 lines
2.6 KiB
Python
import numpy as np
|
|
import torch
|
|
|
|
class Exposure2HDR:
|
|
"""
|
|
DiffusionLight Exposure2HDR class
|
|
|
|
"""
|
|
def __init__(self):
|
|
pass
|
|
|
|
@classmethod
|
|
def INPUT_TYPES(s):
|
|
return {
|
|
"required": {
|
|
"exposures": ("IMAGE",),
|
|
"gamma": ("FLOAT", {
|
|
"default": 2.4,
|
|
"min": -1000,
|
|
"max": 1000,
|
|
"step": 0.01,
|
|
"round": False,
|
|
"display": "number",
|
|
"lazy": True
|
|
}),
|
|
"ev_values": ("STRING", {
|
|
"multiline": False,
|
|
"default": "0.0,-2.5,-5.0",
|
|
"lazy": True
|
|
}),
|
|
},
|
|
}
|
|
|
|
RETURN_TYPES = ("IMAGE",)
|
|
|
|
FUNCTION = "exposure_to_hdr"
|
|
|
|
def exposure_to_hdr(self, exposures, gamma, ev_values):
|
|
"""
|
|
convert multiple image to a single HDR image
|
|
Args:
|
|
exposures (IMAGE): The input environment map image. #Tensor of image format shape (range 0-1) shape [N, H, W, 3]
|
|
gamma (float): The gamma value to apply during the conversion.
|
|
ev_values (str): A comma-separated string of EV values to use for the HDR conversion.
|
|
"""
|
|
# Assuming envmap is already in the correct format
|
|
|
|
ev_values = [float(ev.strip()) for ev in ev_values.split(",")]
|
|
hdr_image = exposure_to_hdr(exposures, gamma, ev_values)[None]
|
|
return (hdr_image, )
|
|
|
|
|
|
def exposure_to_hdr(exposures, gamma, evs):
|
|
|
|
|
|
scaler = np.array([0.212671, 0.715160, 0.072169])
|
|
|
|
|
|
# inital first image
|
|
image0 = exposures[0]
|
|
image0_linear = torch.pow(image0, gamma)
|
|
|
|
# read luminace for every image
|
|
luminances = []
|
|
for i in range(len(evs)):
|
|
image = exposures[i]
|
|
|
|
# apply gama correction
|
|
linear_img = torch.pow(image, gamma)
|
|
|
|
# convert the brighness
|
|
linear_img *= 1 / (2 ** evs[i])
|
|
|
|
# compute luminace
|
|
lumi = linear_img @ scaler
|
|
luminances.append(lumi)
|
|
|
|
# start from darkest image
|
|
out_luminace = luminances[len(evs) - 1]
|
|
for i in range(len(evs) - 1, 0, -1):
|
|
# compute mask
|
|
maxval = 1 / (2 ** evs[i-1])
|
|
p1 = torch.clamp((luminances[i-1] - 0.9 * maxval) / (0.1 * maxval), 0, 1)
|
|
p2 = out_luminace > luminances[i-1]
|
|
mask = (p1 * p2).float()
|
|
out_luminace = luminances[i-1] * (1-mask) + out_luminace * mask
|
|
|
|
hdr_rgb = image0_linear * (out_luminace / (luminances[0] + 1e-10))[:, :, None]
|
|
|
|
return hdr_rgb
|