mirror of
https://github.com/alicevision/Meshroom.git
synced 2025-05-31 09:56:32 +02:00
[nodes] ldrToHdr: automatic brackets estimation (temporary solution)
This commit is contained in:
parent
2401a366e2
commit
1b52bd5cbc
3 changed files with 270 additions and 6 deletions
|
@ -1,13 +1,32 @@
|
||||||
__version__ = "2.0"
|
__version__ = "2.0"
|
||||||
|
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
|
||||||
from meshroom.core import desc
|
from meshroom.core import desc
|
||||||
|
|
||||||
|
def findMetadata(d, keys, defaultValue):
|
||||||
|
v = None
|
||||||
|
for key in keys:
|
||||||
|
v = d.get(key, None)
|
||||||
|
k = key.lower()
|
||||||
|
if v != None:
|
||||||
|
return v
|
||||||
|
for dk, dv in d.iteritems():
|
||||||
|
dkm = dk.lower().replace(" ", "")
|
||||||
|
if dkm == key.lower():
|
||||||
|
return dv
|
||||||
|
dkm = dkm.split(":")[-1]
|
||||||
|
dkm = dkm.split("/")[-1]
|
||||||
|
if dkm == k:
|
||||||
|
return dv
|
||||||
|
return defaultValue
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class LdrToHdrCalibration(desc.CommandLineNode):
|
class LdrToHdrCalibration(desc.CommandLineNode):
|
||||||
commandLine = 'aliceVision_LdrToHdrCalibration {allParams}'
|
commandLine = 'aliceVision_LdrToHdrCalibration {allParams}'
|
||||||
size = desc.DynamicNodeSize('input')
|
size = desc.DynamicNodeSize('input')
|
||||||
#parallelization = desc.Parallelization(blockSize=40)
|
|
||||||
#commandLineRange = '--rangeStart {rangeStart} --rangeSize {rangeBlockSize}'
|
|
||||||
|
|
||||||
documentation = '''
|
documentation = '''
|
||||||
Calibrate LDR to HDR response curve from samples
|
Calibrate LDR to HDR response curve from samples
|
||||||
|
@ -109,3 +128,67 @@ class LdrToHdrCalibration(desc.CommandLineNode):
|
||||||
uid=[],
|
uid=[],
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def update(cls, node):
|
||||||
|
if not isinstance(node.nodeDesc, cls):
|
||||||
|
raise ValueError("Node {} is not an instance of type {}".format(node, cls))
|
||||||
|
# TODO: use Node version for this test
|
||||||
|
if 'userNbBrackets' not in node.getAttributes().keys():
|
||||||
|
# Old version of the node
|
||||||
|
return
|
||||||
|
if node.userNbBrackets.value != 0:
|
||||||
|
node.nbBrackets.value = node.userNbBrackets.value
|
||||||
|
return
|
||||||
|
# logging.info("[LDRToHDR] Update start: version:" + str(node.packageVersion))
|
||||||
|
cameraInitOutput = node.input.getLinkParam(recursive=True)
|
||||||
|
if not cameraInitOutput:
|
||||||
|
node.nbBrackets.value = 0
|
||||||
|
return
|
||||||
|
print("LdrToHdrCalib cameraInitOutput: " + str(cameraInitOutput))
|
||||||
|
viewpoints = cameraInitOutput.node.viewpoints.value
|
||||||
|
print("LdrToHdrCalib viewpoints: " + str(viewpoints))
|
||||||
|
|
||||||
|
# logging.info("[LDRToHDR] Update start: nb viewpoints:" + str(len(viewpoints)))
|
||||||
|
inputs = []
|
||||||
|
for viewpoint in viewpoints:
|
||||||
|
jsonMetadata = viewpoint.metadata.value
|
||||||
|
if not jsonMetadata:
|
||||||
|
# no metadata, we cannot found the number of brackets
|
||||||
|
node.nbBrackets.value = 0
|
||||||
|
return
|
||||||
|
d = json.loads(jsonMetadata)
|
||||||
|
fnumber = findMetadata(d, ["FNumber", "Exif:ApertureValue", "ApertureValue", "Aperture"], "")
|
||||||
|
shutterSpeed = findMetadata(d, ["Exif:ShutterSpeedValue", "ShutterSpeedValue", "ShutterSpeed"], "")
|
||||||
|
iso = findMetadata(d, ["Exif:ISOSpeedRatings", "ISOSpeedRatings", "ISO"], "")
|
||||||
|
if not fnumber and not shutterSpeed:
|
||||||
|
# If one image without shutter or fnumber, we cannot found the number of brackets.
|
||||||
|
# We assume that there is no multi-bracketing, so nothing to do.
|
||||||
|
node.nbBrackets.value = 1
|
||||||
|
return
|
||||||
|
inputs.append((viewpoint.path.value, (fnumber, shutterSpeed, iso)))
|
||||||
|
inputs.sort()
|
||||||
|
|
||||||
|
exposureGroups = []
|
||||||
|
exposures = []
|
||||||
|
for path, exp in inputs:
|
||||||
|
if exposures and exp != exposures[-1] and exp == exposures[0]:
|
||||||
|
exposureGroups.append(exposures)
|
||||||
|
exposures = [exp]
|
||||||
|
else:
|
||||||
|
exposures.append(exp)
|
||||||
|
exposureGroups.append(exposures)
|
||||||
|
exposures = None
|
||||||
|
bracketSizes = set()
|
||||||
|
if len(exposureGroups) == 1:
|
||||||
|
node.nbBrackets.value = 1
|
||||||
|
else:
|
||||||
|
for expGroup in exposureGroups:
|
||||||
|
bracketSizes.add(len(expGroup))
|
||||||
|
if len(bracketSizes) == 1:
|
||||||
|
node.nbBrackets.value = bracketSizes.pop()
|
||||||
|
# logging.info("[LDRToHDR] nb bracket size:" + str(node.nbBrackets.value))
|
||||||
|
else:
|
||||||
|
node.nbBrackets.value = 0
|
||||||
|
# logging.info("[LDRToHDR] Update end")
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,48 @@
|
||||||
__version__ = "2.0"
|
__version__ = "2.0"
|
||||||
|
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
|
||||||
from meshroom.core import desc
|
from meshroom.core import desc
|
||||||
|
|
||||||
|
def findMetadata(d, keys, defaultValue):
|
||||||
|
v = None
|
||||||
|
for key in keys:
|
||||||
|
v = d.get(key, None)
|
||||||
|
k = key.lower()
|
||||||
|
if v != None:
|
||||||
|
return v
|
||||||
|
for dk, dv in d.iteritems():
|
||||||
|
dkm = dk.lower().replace(" ", "")
|
||||||
|
if dkm == key.lower():
|
||||||
|
return dv
|
||||||
|
dkm = dkm.split(":")[-1]
|
||||||
|
dkm = dkm.split("/")[-1]
|
||||||
|
if dkm == k:
|
||||||
|
return dv
|
||||||
|
return defaultValue
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class DividedInputNodeSize(desc.DynamicNodeSize):
|
||||||
|
"""
|
||||||
|
The LDR2HDR will reduce the amount of views in the SfMData.
|
||||||
|
This class converts the number of LDR input views into the number of HDR output views.
|
||||||
|
"""
|
||||||
|
def __init__(self, param, divParam):
|
||||||
|
super(DividedInputNodeSize, self).__init__(param)
|
||||||
|
self._divParam = divParam
|
||||||
|
def computeSize(self, node):
|
||||||
|
s = super(DividedInputNodeSize, self).computeSize(node)
|
||||||
|
divParam = node.attribute(self._divParam)
|
||||||
|
if divParam.value == 0:
|
||||||
|
return s
|
||||||
|
return s / divParam.value
|
||||||
|
|
||||||
|
|
||||||
class LdrToHdrMerge(desc.CommandLineNode):
|
class LdrToHdrMerge(desc.CommandLineNode):
|
||||||
commandLine = 'aliceVision_LdrToHdrMerge {allParams}'
|
commandLine = 'aliceVision_LdrToHdrMerge {allParams}'
|
||||||
size = desc.DynamicNodeSize('input')
|
size = DividedInputNodeSize('input', 'nbBrackets')
|
||||||
#parallelization = desc.Parallelization(blockSize=40)
|
#parallelization = desc.Parallelization(blockSize=40)
|
||||||
#commandLineRange = '--rangeStart {rangeStart} --rangeSize {rangeBlockSize}'
|
#commandLineRange = '--rangeStart {rangeStart} --rangeSize {rangeBlockSize}'
|
||||||
|
|
||||||
|
@ -94,3 +131,65 @@ class LdrToHdrMerge(desc.CommandLineNode):
|
||||||
uid=[],
|
uid=[],
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def update(cls, node):
|
||||||
|
if not isinstance(node.nodeDesc, cls):
|
||||||
|
raise ValueError("Node {} is not an instance of type {}".format(node, cls))
|
||||||
|
# TODO: use Node version for this test
|
||||||
|
if 'userNbBrackets' not in node.getAttributes().keys():
|
||||||
|
# Old version of the node
|
||||||
|
return
|
||||||
|
if node.userNbBrackets.value != 0:
|
||||||
|
node.nbBrackets.value = node.userNbBrackets.value
|
||||||
|
return
|
||||||
|
# logging.info("[LDRToHDR] Update start: version:" + str(node.packageVersion))
|
||||||
|
cameraInitOutput = node.input.getLinkParam(recursive=True)
|
||||||
|
if not cameraInitOutput:
|
||||||
|
node.nbBrackets.value = 0
|
||||||
|
return
|
||||||
|
viewpoints = cameraInitOutput.node.viewpoints.value
|
||||||
|
|
||||||
|
# logging.info("[LDRToHDR] Update start: nb viewpoints:" + str(len(viewpoints)))
|
||||||
|
inputs = []
|
||||||
|
for viewpoint in viewpoints:
|
||||||
|
jsonMetadata = viewpoint.metadata.value
|
||||||
|
if not jsonMetadata:
|
||||||
|
# no metadata, we cannot found the number of brackets
|
||||||
|
node.nbBrackets.value = 0
|
||||||
|
return
|
||||||
|
d = json.loads(jsonMetadata)
|
||||||
|
fnumber = findMetadata(d, ["FNumber", "Exif:ApertureValue", "ApertureValue", "Aperture"], "")
|
||||||
|
shutterSpeed = findMetadata(d, ["Exif:ShutterSpeedValue", "ShutterSpeedValue", "ShutterSpeed"], "")
|
||||||
|
iso = findMetadata(d, ["Exif:ISOSpeedRatings", "ISOSpeedRatings", "ISO"], "")
|
||||||
|
if not fnumber and not shutterSpeed:
|
||||||
|
# If one image without shutter or fnumber, we cannot found the number of brackets.
|
||||||
|
# We assume that there is no multi-bracketing, so nothing to do.
|
||||||
|
node.nbBrackets.value = 1
|
||||||
|
return
|
||||||
|
inputs.append((viewpoint.path.value, (fnumber, shutterSpeed, iso)))
|
||||||
|
inputs.sort()
|
||||||
|
|
||||||
|
exposureGroups = []
|
||||||
|
exposures = []
|
||||||
|
for path, exp in inputs:
|
||||||
|
if exposures and exp != exposures[-1] and exp == exposures[0]:
|
||||||
|
exposureGroups.append(exposures)
|
||||||
|
exposures = [exp]
|
||||||
|
else:
|
||||||
|
exposures.append(exp)
|
||||||
|
exposureGroups.append(exposures)
|
||||||
|
exposures = None
|
||||||
|
bracketSizes = set()
|
||||||
|
if len(exposureGroups) == 1:
|
||||||
|
node.nbBrackets.value = 1
|
||||||
|
else:
|
||||||
|
for expGroup in exposureGroups:
|
||||||
|
bracketSizes.add(len(expGroup))
|
||||||
|
if len(bracketSizes) == 1:
|
||||||
|
node.nbBrackets.value = bracketSizes.pop()
|
||||||
|
# logging.info("[LDRToHDR] nb bracket size:" + str(node.nbBrackets.value))
|
||||||
|
else:
|
||||||
|
node.nbBrackets.value = 0
|
||||||
|
# logging.info("[LDRToHDR] Update end")
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,27 @@
|
||||||
__version__ = "2.0"
|
__version__ = "2.0"
|
||||||
|
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
|
||||||
from meshroom.core import desc
|
from meshroom.core import desc
|
||||||
|
|
||||||
|
def findMetadata(d, keys, defaultValue):
|
||||||
|
v = None
|
||||||
|
for key in keys:
|
||||||
|
v = d.get(key, None)
|
||||||
|
k = key.lower()
|
||||||
|
if v != None:
|
||||||
|
return v
|
||||||
|
for dk, dv in d.iteritems():
|
||||||
|
dkm = dk.lower().replace(" ", "")
|
||||||
|
if dkm == key.lower():
|
||||||
|
return dv
|
||||||
|
dkm = dkm.split(":")[-1]
|
||||||
|
dkm = dkm.split("/")[-1]
|
||||||
|
if dkm == k:
|
||||||
|
return dv
|
||||||
|
return defaultValue
|
||||||
|
|
||||||
|
|
||||||
class LdrToHdrSampling(desc.CommandLineNode):
|
class LdrToHdrSampling(desc.CommandLineNode):
|
||||||
commandLine = 'aliceVision_LdrToHdrSampling {allParams}'
|
commandLine = 'aliceVision_LdrToHdrSampling {allParams}'
|
||||||
|
@ -75,3 +95,65 @@ class LdrToHdrSampling(desc.CommandLineNode):
|
||||||
uid=[],
|
uid=[],
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def update(cls, node):
|
||||||
|
if not isinstance(node.nodeDesc, cls):
|
||||||
|
raise ValueError("Node {} is not an instance of type {}".format(node, cls))
|
||||||
|
# TODO: use Node version for this test
|
||||||
|
if 'userNbBrackets' not in node.getAttributes().keys():
|
||||||
|
# Old version of the node
|
||||||
|
return
|
||||||
|
if node.userNbBrackets.value != 0:
|
||||||
|
node.nbBrackets.value = node.userNbBrackets.value
|
||||||
|
return
|
||||||
|
# logging.info("[LDRToHDR] Update start: version:" + str(node.packageVersion))
|
||||||
|
cameraInitOutput = node.input.getLinkParam()
|
||||||
|
if not cameraInitOutput:
|
||||||
|
node.nbBrackets.value = 0
|
||||||
|
return
|
||||||
|
viewpoints = cameraInitOutput.node.viewpoints.value
|
||||||
|
|
||||||
|
# logging.info("[LDRToHDR] Update start: nb viewpoints:" + str(len(viewpoints)))
|
||||||
|
inputs = []
|
||||||
|
for viewpoint in viewpoints:
|
||||||
|
jsonMetadata = viewpoint.metadata.value
|
||||||
|
if not jsonMetadata:
|
||||||
|
# no metadata, we cannot found the number of brackets
|
||||||
|
node.nbBrackets.value = 0
|
||||||
|
return
|
||||||
|
d = json.loads(jsonMetadata)
|
||||||
|
fnumber = findMetadata(d, ["FNumber", "Exif:ApertureValue", "ApertureValue", "Aperture"], "")
|
||||||
|
shutterSpeed = findMetadata(d, ["Exif:ShutterSpeedValue", "ShutterSpeedValue", "ShutterSpeed"], "")
|
||||||
|
iso = findMetadata(d, ["Exif:ISOSpeedRatings", "ISOSpeedRatings", "ISO"], "")
|
||||||
|
if not fnumber and not shutterSpeed:
|
||||||
|
# If one image without shutter or fnumber, we cannot found the number of brackets.
|
||||||
|
# We assume that there is no multi-bracketing, so nothing to do.
|
||||||
|
node.nbBrackets.value = 1
|
||||||
|
return
|
||||||
|
inputs.append((viewpoint.path.value, (fnumber, shutterSpeed, iso)))
|
||||||
|
inputs.sort()
|
||||||
|
|
||||||
|
exposureGroups = []
|
||||||
|
exposures = []
|
||||||
|
for path, exp in inputs:
|
||||||
|
if exposures and exp != exposures[-1] and exp == exposures[0]:
|
||||||
|
exposureGroups.append(exposures)
|
||||||
|
exposures = [exp]
|
||||||
|
else:
|
||||||
|
exposures.append(exp)
|
||||||
|
exposureGroups.append(exposures)
|
||||||
|
exposures = None
|
||||||
|
bracketSizes = set()
|
||||||
|
if len(exposureGroups) == 1:
|
||||||
|
node.nbBrackets.value = 1
|
||||||
|
else:
|
||||||
|
for expGroup in exposureGroups:
|
||||||
|
bracketSizes.add(len(expGroup))
|
||||||
|
if len(bracketSizes) == 1:
|
||||||
|
node.nbBrackets.value = bracketSizes.pop()
|
||||||
|
# logging.info("[LDRToHDR] nb bracket size:" + str(node.nbBrackets.value))
|
||||||
|
else:
|
||||||
|
node.nbBrackets.value = 0
|
||||||
|
# logging.info("[LDRToHDR] Update end")
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue