diff --git a/meshroom/nodes/aliceVision/LdrToHdrCalibration.py b/meshroom/nodes/aliceVision/LdrToHdrCalibration.py index 516fed769b..54f7cb88d9 100644 --- a/meshroom/nodes/aliceVision/LdrToHdrCalibration.py +++ b/meshroom/nodes/aliceVision/LdrToHdrCalibration.py @@ -5,6 +5,9 @@ import os from collections import Counter +from pyalicevision import sfmData as avsfmdata +from pyalicevision import hdr as avhdr + from meshroom.core import desc from meshroom.core.utils import COLORSPACES, VERBOSE_LEVEL @@ -205,7 +208,7 @@ def update(cls, node): node.nbBrackets.value = 0 return - inputs = [] + inputs = avhdr.vectorli() for viewpoint in viewpoints: jsonMetadata = viewpoint.metadata.value if not jsonMetadata: @@ -232,97 +235,22 @@ def update(cls, node): # We assume that there is no multi-bracketing, so nothing to do. node.nbBrackets.value = 1 return - inputs.append((viewpoint.path.value, (float(fnumber), float(shutterSpeed), float(iso)))) - inputs.sort() - - exposureGroups = [] - exposures = [] - prevFnumber = 0.0 - prevShutterSpeed = 0.0 - prevIso = 0.0 - prevPath = None # Stores the dirname of the previous parsed image - prevExposure = None - newGroup = False # True if a new exposure group needs to be created (useful when there are several datasets) - for path, exp in inputs: - # If the dirname of the previous image and the dirname of the current image do not match, this means that the - # dataset that is being parsed has changed. A new group needs to be created but will fail to be detected in the - # next "if" statement if the new dataset's exposure levels are different. Setting "newGroup" to True prevents this - # from happening. - if prevPath is not None and prevPath != os.path.dirname(path): - newGroup = True - - currentExposure = LdrToHdrCalibration.getExposure(exp) - # Create a new group if the current image's exposure level is smaller than the previous image's, or - # if a new dataset has been detected (with a change in the path of the images). - if prevExposure and currentExposure < prevExposure or newGroup: - exposureGroups.append(exposures) - exposures = [exp] - else: - exposures.append(exp) + exposure = LdrToHdrCalibration.getExposure((float(fnumber), float(shutterSpeed), float(iso))) - prevPath = os.path.dirname(path) - prevExposure = currentExposure - newGroup = False + obj = avhdr.LuminanceInfo(viewpoint.viewId.value,viewpoint.path.value, exposure) + inputs.append(obj) - exposureGroups.append(exposures) + obj = avhdr.estimateGroups(inputs) - exposures = None - bracketSizes = Counter() - if len(exposureGroups) == 1: - if len(set(exposureGroups[0])) == 1: - # Single exposure and multiple views - node.nbBrackets.value = 1 - else: - # Single view and multiple exposures - node.nbBrackets.value = len(exposureGroups[0]) - else: - for expGroup in exposureGroups: - bracketSizes[len(expGroup)] += 1 - - if len(bracketSizes) == 0: - node.nbBrackets.value = 0 - else: - bestTuple = None - for tuple in bracketSizes.most_common(): - if bestTuple is None or tuple[1] > bestTuple[1]: - bestTuple = tuple - elif tuple[1] == bestTuple[1]: - bestTuple = tuple if tuple[0] > bestTuple[0] else bestTuple + if len(obj) == 0: + node.nbBrackets.value = 0 + return - bestBracketSize = bestTuple[0] - node.nbBrackets.value = bestBracketSize + node.nbBrackets.value = len(obj[0]) @staticmethod def getExposure(exp, refIso = 100.0, refFnumber = 1.0): fnumber, shutterSpeed, iso = exp - - validShutterSpeed = shutterSpeed > 0.0 and math.isfinite(shutterSpeed) - validFnumber = fnumber > 0.0 and math.isfinite(fnumber) - - if not validShutterSpeed and not validFnumber: - return -1.0 - - validRefFnumber = refFnumber > 0.0 and math.isfinite(refFnumber) - - if not validShutterSpeed: - shutterSpeed = 1.0 / 200.0 - - if not validFnumber: - if validRefFnumber: - fnumber = refFnumber - else: - fnumber = 2.0 - - lRefFnumber = refFnumber - if not validRefFnumber: - lRefFnumber = fnumber - - isoToAperture = 1.0 - if iso > 1e-6 and refIso > 1e-6: - isoToAperture = math.sqrt(iso / refIso) - - newFnumber = fnumber * isoToAperture - expIncrease = (lRefFnumber / newFnumber) * (lRefFnumber / newFnumber) - - return shutterSpeed * expIncrease + obj = avsfmdata.ExposureSetting(shutterSpeed, fnumber, iso) + return obj.getExposure() diff --git a/meshroom/nodes/aliceVision/LdrToHdrMerge.py b/meshroom/nodes/aliceVision/LdrToHdrMerge.py index acc080342a..d30b6d6d66 100644 --- a/meshroom/nodes/aliceVision/LdrToHdrMerge.py +++ b/meshroom/nodes/aliceVision/LdrToHdrMerge.py @@ -5,6 +5,9 @@ import math from collections import Counter +from pyalicevision import sfmData as avsfmdata +from pyalicevision import hdr as avhdr + from meshroom.core import desc from meshroom.core.utils import COLORSPACES, EXR_STORAGE_DATA_TYPE, VERBOSE_LEVEL @@ -278,7 +281,7 @@ def update(cls, node): node.nbBrackets.value = 0 return - inputs = [] + inputs = avhdr.vectorli() for viewpoint in viewpoints: jsonMetadata = viewpoint.metadata.value if not jsonMetadata: @@ -305,100 +308,25 @@ def update(cls, node): # We assume that there is no multi-bracketing, so nothing to do. node.nbBrackets.value = 1 return - inputs.append((viewpoint.path.value, (float(fnumber), float(shutterSpeed), float(iso)))) - inputs.sort() - - exposureGroups = [] - exposures = [] - prevFnumber = 0.0 - prevShutterSpeed = 0.0 - prevIso = 0.0 - prevPath = None # Stores the dirname of the previous parsed image - prevExposure = None - newGroup = False # True if a new exposure group needs to be created (useful when there are several datasets) - for path, exp in inputs: - # If the dirname of the previous image and the dirname of the current image do not match, this means that the - # dataset that is being parsed has changed. A new group needs to be created but will fail to be detected in the - # next "if" statement if the new dataset's exposure levels are different. Setting "newGroup" to True prevents this - # from happening. - if prevPath is not None and prevPath != os.path.dirname(path): - newGroup = True - - currentExposure = LdrToHdrMerge.getExposure(exp) - # Create a new group if the current image's exposure level is smaller than the previous image's, or - # if a new dataset has been detected (with a change in the path of the images). - if prevExposure and currentExposure < prevExposure or newGroup: - exposureGroups.append(exposures) - exposures = [exp] - else: - exposures.append(exp) + exposure = LdrToHdrMerge.getExposure((float(fnumber), float(shutterSpeed), float(iso))) - prevPath = os.path.dirname(path) - prevExposure = currentExposure - newGroup = False + obj = avhdr.LuminanceInfo(viewpoint.viewId.value,viewpoint.path.value, exposure) + inputs.append(obj) - exposureGroups.append(exposures) + obj = avhdr.estimateGroups(inputs) - exposures = None - bracketSizes = Counter() - if len(exposureGroups) == 1: - if len(set(exposureGroups[0])) == 1: - # Single exposure and multiple views - node.nbBrackets.value = 1 - else: - # Single view and multiple exposures - node.nbBrackets.value = len(exposureGroups[0]) - else: - for expGroup in exposureGroups: - bracketSizes[len(expGroup)] += 1 - - if len(bracketSizes) == 0: - node.nbBrackets.value = 0 - else: - bestTuple = None - for tuple in bracketSizes.most_common(): - if bestTuple is None or tuple[1] > bestTuple[1]: - bestTuple = tuple - elif tuple[1] == bestTuple[1]: - bestTuple = tuple if tuple[0] > bestTuple[0] else bestTuple + if len(obj) == 0: + node.nbBrackets.value = 0 + return - bestBracketSize = bestTuple[0] - node.nbBrackets.value = bestBracketSize + node.nbBrackets.value = len(obj[0]) @staticmethod def getExposure(exp, refIso = 100.0, refFnumber = 1.0): fnumber, shutterSpeed, iso = exp - - validShutterSpeed = shutterSpeed > 0.0 and math.isfinite(shutterSpeed) - validFnumber = fnumber > 0.0 and math.isfinite(fnumber) - - if not validShutterSpeed and not validFnumber: - return -1.0 - - validRefFnumber = refFnumber > 0.0 and math.isfinite(refFnumber) - - if not validShutterSpeed: - shutterSpeed = 1.0 / 200.0 - - if not validFnumber: - if validRefFnumber: - fnumber = refFnumber - else: - fnumber = 2.0 - - lRefFnumber = refFnumber - if not validRefFnumber: - lRefFnumber = fnumber - - isoToAperture = 1.0 - if iso > 1e-6 and refIso > 1e-6: - isoToAperture = math.sqrt(iso / refIso) - - newFnumber = fnumber * isoToAperture - expIncrease = (lRefFnumber / newFnumber) * (lRefFnumber / newFnumber) - - return shutterSpeed * expIncrease + obj = avsfmdata.ExposureSetting(shutterSpeed, fnumber, iso) + return obj.getExposure() def processChunk(self, chunk): # Trick to avoid sending --nbBrackets to the command line when the bracket detection is automatic. diff --git a/meshroom/nodes/aliceVision/LdrToHdrSampling.py b/meshroom/nodes/aliceVision/LdrToHdrSampling.py index 64dd7ee37e..3646c892cf 100644 --- a/meshroom/nodes/aliceVision/LdrToHdrSampling.py +++ b/meshroom/nodes/aliceVision/LdrToHdrSampling.py @@ -5,6 +5,9 @@ import os from collections import Counter +from pyalicevision import sfmData as avsfmdata +from pyalicevision import hdr as avhdr + from meshroom.core import desc from meshroom.core.utils import COLORSPACES, VERBOSE_LEVEL @@ -231,7 +234,7 @@ def update(cls, node): node.nbBrackets.value = 0 return - inputs = [] + inputs = avhdr.vectorli() for viewpoint in viewpoints: jsonMetadata = viewpoint.metadata.value if not jsonMetadata: @@ -258,99 +261,26 @@ def update(cls, node): # We assume that there is no multi-bracketing, so nothing to do. node.nbBrackets.value = 1 return - inputs.append((viewpoint.path.value, (float(fnumber), float(shutterSpeed), float(iso)))) - inputs.sort() - - exposureGroups = [] - exposures = [] - prevFnumber = 0.0 - prevShutterSpeed = 0.0 - prevIso = 0.0 - prevPath = None # Stores the dirname of the previous parsed image - prevExposure = None - newGroup = False # True if a new exposure group needs to be created (useful when there are several datasets) - for path, exp in inputs: - # If the dirname of the previous image and the dirname of the current image do not match, this means that the - # dataset that is being parsed has changed. A new group needs to be created but will fail to be detected in the - # next "if" statement if the new dataset's exposure levels are different. Setting "newGroup" to True prevents this - # from happening. - if prevPath is not None and prevPath != os.path.dirname(path): - newGroup = True - - currentExposure = LdrToHdrSampling.getExposure(exp) - # Create a new group if the current image's exposure level is smaller than the previous image's, or - # if a new dataset has been detected (with a change in the path of the images). - if prevExposure and currentExposure < prevExposure or newGroup: - exposureGroups.append(exposures) - exposures = [exp] - else: - exposures.append(exp) + exposure = LdrToHdrSampling.getExposure((float(fnumber), float(shutterSpeed), float(iso))) - prevPath = os.path.dirname(path) - prevExposure = currentExposure - newGroup = False + obj = avhdr.LuminanceInfo(viewpoint.viewId.value,viewpoint.path.value, exposure) + inputs.append(obj) - exposureGroups.append(exposures) + obj = avhdr.estimateGroups(inputs) - exposures = None - bracketSizes = Counter() - if len(exposureGroups) == 1: - if len(set(exposureGroups[0])) == 1: - # Single exposure and multiple views - node.nbBrackets.value = 1 - else: - # Single view and multiple exposures - node.nbBrackets.value = len(exposureGroups[0]) - else: - for expGroup in exposureGroups: - bracketSizes[len(expGroup)] += 1 + if len(obj) == 0: + node.nbBrackets.value = 0 + return - if len(bracketSizes) == 0: - node.nbBrackets.value = 0 - else: - bestTuple = None - for tuple in bracketSizes.most_common(): - if bestTuple is None or tuple[1] > bestTuple[1]: - bestTuple = tuple - elif tuple[1] == bestTuple[1]: - bestTuple = tuple if tuple[0] > bestTuple[0] else bestTuple + bracketSize = len(obj[0]) + bracketCount = len(obj) - bestBracketSize = bestTuple[0] - bestCount = bestTuple[1] - node.outliersNb = len(inputs) - (bestBracketSize * bestCount) # Compute number of outliers - node.nbBrackets.value = bestBracketSize + node.nbBrackets.value = bracketSize + node.outliersNb = len(inputs) - (bracketSize * bracketCount) @staticmethod def getExposure(exp, refIso = 100.0, refFnumber = 1.0): fnumber, shutterSpeed, iso = exp - - validShutterSpeed = shutterSpeed > 0.0 and math.isfinite(shutterSpeed) - validFnumber = fnumber > 0.0 and math.isfinite(fnumber) - - if not validShutterSpeed and not validFnumber: - return -1.0 - - validRefFnumber = refFnumber > 0.0 and math.isfinite(refFnumber) - - if not validShutterSpeed: - shutterSpeed = 1.0 / 200.0 - - if not validFnumber: - if validRefFnumber: - fnumber = refFnumber - else: - fnumber = 2.0 - - lRefFnumber = refFnumber - if not validRefFnumber: - lRefFnumber = fnumber - - isoToAperture = 1.0 - if iso > 1e-6 and refIso > 1e-6: - isoToAperture = math.sqrt(iso / refIso) - - newFnumber = fnumber * isoToAperture - expIncrease = (lRefFnumber / newFnumber) * (lRefFnumber / newFnumber) - - return shutterSpeed * expIncrease + obj = avsfmdata.ExposureSetting(shutterSpeed, fnumber, iso) + return obj.getExposure()