Skip to content

Commit

Permalink
[nodes][SfMFilter] update SfMFilter node
Browse files Browse the repository at this point in the history
- update parameters
- update documentation
- parameters are grouped by steps for better understanding and control
  • Loading branch information
almarouk committed Oct 10, 2023
1 parent f20f0ab commit b35807a
Show file tree
Hide file tree
Showing 2 changed files with 278 additions and 27 deletions.
28 changes: 10 additions & 18 deletions meshroom/nodes/aliceVision/PrepareDenseScene.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,29 +92,21 @@ class PrepareDenseScene(desc.AVCommandLineNode):
desc.FloatParam(
name="landmarksMaskScale",
label="Landmarks Mask Scale",
description="Scale (relative to image size) of the projection of landmarks"
" to mask images for depth computation.\n"
"If 0, masking using landmarks will not be used.",
description="Scale of the projection of landmarks to mask images for depth computation.\n"
"If 0, masking using landmarks will not be used.\n"
"Otherwise, it's used to scale the projection radius \n"
"(either specified by `inputRadiiFile` or by image size if the former is not given).",
value=0.,
range=(0.0, 1.0, 0.01),
uid=[0],
advanced=True
),
desc.IntParam(
name="nbNeighborObservations",
label="Number of Neighbor Observations",
description="Number of neighbor observations to be considered for the landmarks-based masking.",
value=5,
range=(0, 50, 1),
uid=[0],
advanced=True
),
desc.FloatParam(
name="percentile",
label="Percentile",
description="TODO.",
value=0.95,
range=(0.0, 1.0, 0.01),
desc.File(
name="inputRadiiFile",
label="Input Radii File",
description="Input Radii file containing the estimated projection radius of landmarks per view. \n"
"If not specified, image size will be used to specify the radius.",
value="",
uid=[0],
advanced=True
),
Expand Down
277 changes: 268 additions & 9 deletions meshroom/nodes/aliceVision/SfMFilter.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,12 @@ class SfMFilter(desc.AVCommandLineNode):
documentation = '''
This node allows to filter the SfM data.
It filters the landmark observations to allow a limited number of observations.
It filters the landmarks having:
- an insufficient number of observations
- a large pixel size compared to their neighbors.
It also filters the landmark observations to allow only a limited number
of observations per landmark; the nearest observations are kept.
'''

inputs = [
Expand All @@ -23,14 +28,252 @@ class SfMFilter(desc.AVCommandLineNode):
value="",
uid=[0],
),
desc.IntParam(
name="maxNbObservationsPerLandmark",
label="Maximum Nb of Observations per Landmark",
description="Maximum number of allowed observations per landmark.",
value=5,
range=(0, 50000, 1),
advanced=True,
uid=[0],
desc.GroupAttribute(
name="filterParams",
label="Filter Parameters",
description="Filter Parameters.",
joinChar=":",
groupDesc=[
desc.GroupAttribute(
name="filterLandmarks",
label="Filter Landmarks",
description="Filter Landmarks over multiple steps",
joinChar=":",
groupDesc=[
desc.BoolParam(
name="filterLandmarksEnabled",
label="Enable",
description="Enable Landmarks Filtering.",
value=True,
uid=[0],
),
desc.GroupAttribute(
name="step1",
label="Step 1",
description="Remove landmarks with insufficient observations",
joinChar=":",
enabled=lambda node: node.filterParams.filterLandmarks.filterLandmarksEnabled.value,
groupDesc=[
desc.BoolParam(
name="step1Enabled",
label="Enable",
description="Enable Step 1.",
value=True,
uid=[0],
),
desc.IntParam(
name="minNbObservationsPerLandmark",
label="Minimum Nb of Observations",
description="Minimum number of observations required to keep a landmark.",
value=3,
range=(0, 20, 1),
enabled=lambda node: node.filterParams.filterLandmarks.filterLandmarksEnabled.value
and node.filterParams.filterLandmarks.step1.step1Enabled.value,
uid=[0],
)
]
),
desc.GroupAttribute(
name="step2",
label="Step 2",
description="Remove landmarks with dissimilar observations of 3D landmark neighbors",
joinChar=":",
enabled=lambda node: node.filterParams.filterLandmarks.filterLandmarksEnabled.value,
groupDesc=[
desc.BoolParam(
name="step2Enabled",
label="Enable",
description="Enable Step 2.",
value=True,
uid=[0],
),
desc.IntParam(
name="maxNbObservationsPerLandmark",
label="Maximum Nb of Observations",
description="Maximum number of allowed observations per landmark.",
value=2,
range=(0, 20, 1),
enabled=lambda node: node.filterParams.filterLandmarks.filterLandmarksEnabled.value
and node.filterParams.filterLandmarks.step2.step2Enabled.value,
uid=[0],
),
desc.IntParam(
name="nbNeighbors3D",
label="Nb of Neighbors in 3D",
description="Number of neighbor landmarks used in making the decision for best observations.",
value=10,
range=(1, 50, 1),
enabled=lambda node: node.filterParams.filterLandmarks.filterLandmarksEnabled.value
and node.filterParams.filterLandmarks.step2.step2Enabled.value,
uid=[0],
)
]
),
desc.GroupAttribute(
name="step3",
label="Step 3",
description="Remove landmarks with worse resolution than neighbors",
joinChar=":",
enabled=lambda node: node.filterParams.filterLandmarks.filterLandmarksEnabled.value,
groupDesc=[
desc.BoolParam(
name="step3Enabled",
label="Enable",
description="Enable Step 3.",
value=True,
uid=[0],
),
desc.FloatParam(
name="radiusScale",
label="Radius Scale",
description="Scale factor applied to pixel size based radius filter applied to landmarks.",
value=2.,
range=(0., 20., 1.),
enabled=lambda node: node.filterParams.filterLandmarks.filterLandmarksEnabled.value
and node.filterParams.filterLandmarks.step3.step3Enabled.value,
uid=[0],
),
desc.BoolParam(
name="useFeatureScale",
label="Use Feature Scale",
description="If true, use feature scale for computing pixel size. Otherwise, use a scale of 1 pixel.",
value=True,
enabled=lambda node: node.filterParams.filterLandmarks.filterLandmarksEnabled.value
and node.filterParams.filterLandmarks.step3.step3Enabled.value,
uid=[0],
)
]
)
]
),
desc.GroupAttribute(
name="filterObservations3D",
label="Filter Observations 3D",
description="Select best observations for observation consistency between 3D neighboring landmarks",
joinChar=":",
groupDesc=[
desc.BoolParam(
name="filterObservations3DEnabled",
label="Enable",
description="Enable Observations Filtering in 3D.",
value=True,
uid=[0],
),
desc.IntParam(
name="maxNbObservationsPerLandmark",
label="Maximum Nb of Observations",
description="Maximum number of allowed observations per landmark.",
value=2,
range=(0, 20, 1),
enabled=lambda node: node.filterParams.filterObservations3D.filterObservations3DEnabled.value,
uid=[0],
),
desc.BoolParam(
name="propagationEnabled",
label="Enable Neighbors Influence",
description="Enable propagating neighbors' scores iteratively.",
value=True,
enabled=lambda node: node.filterParams.filterObservations3D.filterObservations3DEnabled.value,
uid=[0],
),
desc.IntParam(
name="nbNeighbors3D",
label="Nb of Neighbors in 3D",
description="Number of neighbor landmarks used in making the decision for best observations.",
value=10,
range=(1, 50, 1),
enabled=lambda node: node.filterParams.filterObservations3D.filterObservations3DEnabled.value
and node.filterParams.filterObservations3D.propagationEnabled.value,
uid=[0],
),
desc.FloatParam(
name="neighborsInfluence",
label="Neighbors Influence",
description="Specifies how much influential the neighbors are in selecting the best observations. "
"Between 0. and 1., the closer to 1., the more influencial the neighborhood is.",
value=.5,
range=(0., 1., .1),
enabled=lambda node: node.filterParams.filterObservations3D.filterObservations3DEnabled.value
and node.filterParams.filterObservations3D.propagationEnabled.value,
uid=[0],
),
desc.IntParam(
name="nbIterations",
label="Nb of Iterations",
description="Number of iterations to propagate neighbors information.",
value=5,
range=(1, 100, 1),
enabled=lambda node: node.filterParams.filterObservations3D.filterObservations3DEnabled.value
and node.filterParams.filterObservations3D.propagationEnabled.value,
uid=[0],
),
desc.BoolParam(
name="dampingEnabled",
label="Enable damping",
description="Enable additional damping of observations to reject after each iterations.",
value=True,
enabled=lambda node: node.filterParams.filterObservations3D.filterObservations3DEnabled.value
and node.filterParams.filterObservations3D.propagationEnabled.value,
uid=[0],
),
desc.FloatParam(
name="dampingFactor",
label="Damping Factor",
description="Multiplicative damping factor.",
value=.5,
range=(0., 1., .1),
enabled=lambda node: node.filterParams.filterObservations3D.filterObservations3DEnabled.value
and node.filterParams.filterObservations3D.propagationEnabled.value
and node.filterParams.filterObservations3D.dampingEnabled.value,
uid=[0],
)
]
),
desc.GroupAttribute(
name="filterObservations2D",
label="Filter Observations 2D",
description="Select best observations for observation consistency between 2D projected neighboring "
"landmarks per view.\nEventually remove landmarks with no remaining observations.\n"
"Also estimate depth map mask radius per view based on landmarks.",
joinChar=":",
groupDesc=[
desc.BoolParam(
name="filterObservations2DEnabled",
label="Enable",
description="Enable Observations Filtering in 2D.",
value=True,
uid=[0],
),
desc.IntParam(
name="nbNeighbors2D",
label="Nb of Neighbors in 2D",
description="Number of neighbor observations to be considered for the landmarks-based masking.",
value=5,
range=(1, 50, 1),
enabled=lambda node: node.filterParams.filterObservations2D.filterObservations2DEnabled.value,
uid=[0],
),
desc.FloatParam(
name="percentile",
label="Percentile",
description="Used as a quantile probability for filtering relatively outlier observations.",
value=.95,
range=(0., 1., .01),
enabled=lambda node: node.filterParams.filterObservations2D.filterObservations2DEnabled.value,
uid=[0],
),
desc.FloatParam(
name="maskRadiusThreshold",
label="Mask Radius Threshold",
description="Percentage of image size to be used as an upper limit for estimated mask radius.",
value=.1,
range=(0., 1., .1),
enabled=lambda node: node.filterParams.filterObservations2D.filterObservations2DEnabled.value,
uid=[0],
)
]
)
]
),
desc.ListAttribute(
elementDesc=desc.File(
Expand Down Expand Up @@ -66,6 +309,15 @@ class SfMFilter(desc.AVCommandLineNode):
uid=[], # TODO: 0
joinChar=",",
),
desc.ChoiceParam(
name="verboseLevel",
label="Verbose Level",
description="Verbosity level (fatal, error, warning, info, debug, trace).",
value="info",
values=["fatal", "error", "warning", "info", "debug", "trace"],
exclusive=True,
uid=[],
),
]

outputs = [
Expand All @@ -76,4 +328,11 @@ class SfMFilter(desc.AVCommandLineNode):
value=lambda attr: desc.Node.internalFolder + (os.path.splitext(os.path.basename(attr.node.input.value))[0] or "sfmData") + ".abc",
uid=[],
),
desc.File(
name="outputRadiiFile",
label="Output Radii File",
description="Output Radii file containing the estimated projection radius of observations per view.",
value=lambda attr: desc.Node.internalFolder + (os.path.splitext(os.path.basename(attr.node.input.value))[0] or "radii") + ".txt",
uid=[],
),
]

0 comments on commit b35807a

Please sign in to comment.