https://github.com/yalcinerbora/meturay
Tip revision: 9d7589473e6e7066be282e74038352c761c170d3 authored by Bora Yalciner on 25 June 2024, 16:08:59 UTC
Change small typo on README.md
Change small typo on README.md
Tip revision: 9d75894
mray_sdr_gen.py
import os
os.environ["OPENCV_IO_ENABLE_OPENEXR"] = "1"
from typing import Any
import flip_api
import data as flip_tools
import re
import matplotlib.pyplot as plt
import multiprocessing as mp
import glob
import sys
import cv2
import numpy as np
from math import log10, sqrt
import imageio as io
def stripName(fname):
return fname[fname.rfind('/') + 1 : fname.rfind('.')]
def stripExt(fname):
return fname[0: fname.rfind('.')]
def BGR2Yxy(bgrMatrix):
x = 0.4124 * bgrMatrix[:,:, 2] + 0.3576 * bgrMatrix[:,:, 1] + 0.1805 * bgrMatrix[:,:, 0]
y = 0.2126 * bgrMatrix[:,:, 2] + 0.7152 * bgrMatrix[:,:, 1] + 0.0722 * bgrMatrix[:,:, 0]
z = 0.0193 * bgrMatrix[:,:, 2] + 0.1192 * bgrMatrix[:,:, 1] + 0.9505 * bgrMatrix[:,:, 0]
invSum = 1 / (x + y + z + 0.0001)
result = np.zeros(bgrMatrix.shape, dtype=np.float32)
result[:,:,0] = y
result[:,:,1] = x * invSum
result[:,:,2] = y * invSum
return result
def Yxy2BGR(yxyMatrix):
yy = (yxyMatrix[:,:, 0] / (yxyMatrix[:,:, 2] + 0.01))
x = yxyMatrix[:,:, 1] * yy
y = yxyMatrix[:,:, 0]
z = (1 - yxyMatrix[:,:, 1] - yxyMatrix[:,:, 2]) * yy
result = np.zeros(yxyMatrix.shape, dtype=np.float32)
result[:,:,2] = 3.2410 * x - 1.5374 * y - 0.4986 * z
result[:,:,1] = -0.9692 * x + 1.8760 * y + 0.0416 * z
result[:,:,0] = 0.0556 * x - 0.2040 * y + 1.0567 * z
return result
def Tonemap(inHDR, Lwhite = None, Key = None):
Yxy = BGR2Yxy(inHDR)
# Tonemap Reinhard using Lwhite
imgLum = Yxy[:,:,0]
if Key is None:
Key = np.sum(np.log(imgLum + 0.0001))
Key = np.exp(Key / (imgLum.shape[0] * imgLum.shape[1]))
# Reinhard 2002 Eq.1-2
imgLum = (0.18 / Key) * imgLum
if Lwhite is None:
Lwhite = np.max(imgLum)
# Reinhard 2002 Eq.4
lwSqr = Lwhite * Lwhite
imgLumAdj = (imgLum * (1 + (imgLum / lwSqr))) / (1 + imgLum)
# Only adjust luminance
imgTM = Yxy
imgTM[:,:,0] = imgLumAdj
imgTM = Yxy2BGR(imgTM)
# Gamma
imgTM = np.abs(imgTM) ** (1.0/2.2)
imgTM = (imgTM * 255).clip(0, 255)
imgTM = imgTM.astype(np.uint8)
return (imgTM, Lwhite, Key)
class ToneMapFunctor:
def __init__(self, region, Lwhite, Key):
self.region = region
self.LwhiteRef = Lwhite
self.KeyRef = Key
def __call__(self, samples) -> Any:
image = cv2.imread(samples[1], cv2.IMREAD_UNCHANGED)
roiImg = image[self.region[2]:self.region[3],
self.region[0]:self.region[1]]
#sdr, lw, k = Tonemap(roiImg, Lwhite = self.LwhiteRef, Key = self.KeyRef)
sdr, lw, k = Tonemap(roiImg, Key = self.KeyRef)
#sdr, lw, k = Tonemap(roiImg)
cv2.imwrite(stripExt(samples[1]) + "_tm.jpg", sdr, [cv2.IMWRITE_JPEG_QUALITY, 100])
print("ImgDone: Key {} Lwhite {} '{}'".format(str(k), str(lw), samples[1]))
def main():
args = sys.argv[1:]
if len(args) < 4:
print("Not enough arguments!")
return
refFile : str = args[0]
timeCount : float = float(args[1])
intList = args[2].split(',')
region = (int(intList[0]), int(intList[0]) + int(intList[2]),
int(intList[1]), int(intList[1]) + int(intList[3]))
checkFileRegexList : str = args[3:]
fileDict = {}
sortedDict={}
i = 0
for reg in checkFileRegexList:
data = glob.glob(reg)
print(reg)
for d in data:
seedSpp = re.findall(r"[+-]?\d+(?:\.\d+)?", d)
seedSpp = float(seedSpp[-1])
if seedSpp > timeCount:
continue
if i not in fileDict:
fileDict[i] = {}
fileDict[i][seedSpp] = d
sortedDict[i] = dict(sorted(fileDict[i].items()))
i = i + 1
# Load Exr image and tone map it as well
imRef = cv2.imread(refFile, cv2.IMREAD_UNCHANGED)
roiRef = imRef[region[2]:region[3], region[0]:region[1]]
roiRefSDR, Lwhite, Key = Tonemap(roiRef)
cv2.imwrite(stripExt(refFile) + "_tm.jpg", roiRefSDR, [cv2.IMWRITE_JPEG_QUALITY, 100])
print("Reference: Key {} Lwhite {}".format(str(Key), str(Lwhite)))
with mp.Pool(processes = mp.cpu_count()) as p:
for d in sortedDict.items():
print(d[0])
p.map(ToneMapFunctor(region, Lwhite, Key), d[1].items())
if __name__ == "__main__":
main()