mirror of
https://github.com/alicevision/Meshroom.git
synced 2025-06-05 12:21:59 +02:00
[nodes] HDR Fusion: Align bracket detection with AliceVision's
The bracket detection performed in Meshroom used to differ from the one performed in AliceVision. The metadata that were retrieved to perform the exposure comparisons were not the same, and where AliceVision was actually computing an exposure value, Meshroom was just performing a comparison between the shutter speed, fnumber and ISO values, which resulted in less accurate groups. The `getExposure` static method that is added to the `LdrToHdrSampling`, `LdrToHdrCalibration` and `LdrToHdrMerge` node is the pythonic version of the `getExposure` method from the View class in AliceVision.
This commit is contained in:
parent
9db9337d66
commit
ea8d619fb1
3 changed files with 168 additions and 33 deletions
|
@ -1,6 +1,7 @@
|
|||
__version__ = "4.0"
|
||||
|
||||
import json
|
||||
import math
|
||||
import os
|
||||
from collections import Counter
|
||||
|
||||
|
@ -231,9 +232,20 @@ Sample pixels from Low range images for HDR creation.
|
|||
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"], "")
|
||||
|
||||
# Find Fnumber
|
||||
fnumber = findMetadata(d, ["FNumber"], "")
|
||||
if fnumber == "":
|
||||
aperture = findMetadata(d, ["Exif:ApertureValue", "ApertureValue", "Aperture"], "")
|
||||
if aperture == "":
|
||||
fnumber = -1.0
|
||||
else:
|
||||
fnumber = pow(2.0, aperture / 2.0)
|
||||
|
||||
# Get shutter speed and ISO
|
||||
shutterSpeed = findMetadata(d, ["ExposureTime", "Exif:ShutterSpeedValue", "ShutterSpeedValue", "ShutterSpeed"], -1.0)
|
||||
iso = findMetadata(d, ["Exif:PhotographicSensitivity", "PhotographicSensitivity", "Photographic Sensitivity", "ISO"], -1.0)
|
||||
|
||||
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.
|
||||
|
@ -248,6 +260,7 @@ Sample pixels from Low range images for HDR creation.
|
|||
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
|
||||
|
@ -257,20 +270,18 @@ Sample pixels from Low range images for HDR creation.
|
|||
if prevPath is not None and prevPath != os.path.dirname(path):
|
||||
newGroup = True
|
||||
|
||||
# A new group is created if the current image's exposure level is larger than the previous image's, if there
|
||||
# were any changes in the ISO or aperture value, or if a new dataset has been detected with the path.
|
||||
# Since the input images are ordered, the shutter speed should always be decreasing, so a shutter speed larger
|
||||
# than the previous one indicates the start of a new exposure group.
|
||||
fnumber, shutterSpeed, iso = exp
|
||||
if exposures:
|
||||
prevFnumber, prevShutterSpeed, prevIso = exposures[-1]
|
||||
if exposures and len(exposures) > 1 and (fnumber > prevFnumber or shutterSpeed > prevShutterSpeed or iso < prevIso) or newGroup:
|
||||
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)
|
||||
|
||||
prevPath = os.path.dirname(path)
|
||||
prevExposure = currentExposure
|
||||
newGroup = False
|
||||
|
||||
exposureGroups.append(exposures)
|
||||
|
@ -302,3 +313,37 @@ Sample pixels from Low range images for HDR creation.
|
|||
bestCount = bestTuple[1]
|
||||
node.outliersNb = len(inputs) - (bestBracketSize * bestCount) # Compute number of outliers
|
||||
node.nbBrackets.value = bestBracketSize
|
||||
|
||||
@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 = (newFnumber / lRefFnumber) * (newFnumber / lRefFnumber)
|
||||
|
||||
return shutterSpeed * expIncrease
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue