mirror of
https://github.com/alicevision/Meshroom.git
synced 2025-05-29 08:56:33 +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"
|
||||
|
||||
import json
|
||||
import os
|
||||
|
||||
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):
|
||||
commandLine = 'aliceVision_LdrToHdrCalibration {allParams}'
|
||||
size = desc.DynamicNodeSize('input')
|
||||
#parallelization = desc.Parallelization(blockSize=40)
|
||||
#commandLineRange = '--rangeStart {rangeStart} --rangeSize {rangeBlockSize}'
|
||||
|
||||
documentation = '''
|
||||
Calibrate LDR to HDR response curve from samples
|
||||
|
@ -109,3 +128,67 @@ class LdrToHdrCalibration(desc.CommandLineNode):
|
|||
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"
|
||||
|
||||
import json
|
||||
import os
|
||||
|
||||
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):
|
||||
commandLine = 'aliceVision_LdrToHdrMerge {allParams}'
|
||||
size = desc.DynamicNodeSize('input')
|
||||
size = DividedInputNodeSize('input', 'nbBrackets')
|
||||
#parallelization = desc.Parallelization(blockSize=40)
|
||||
#commandLineRange = '--rangeStart {rangeStart} --rangeSize {rangeBlockSize}'
|
||||
|
||||
|
@ -94,3 +131,65 @@ class LdrToHdrMerge(desc.CommandLineNode):
|
|||
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"
|
||||
|
||||
import json
|
||||
import os
|
||||
|
||||
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):
|
||||
commandLine = 'aliceVision_LdrToHdrSampling {allParams}'
|
||||
|
@ -75,3 +95,65 @@ class LdrToHdrSampling(desc.CommandLineNode):
|
|||
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