Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[nodes] Distortion calibration #1986

Merged
merged 11 commits into from
Jun 2, 2023
Merged
39 changes: 39 additions & 0 deletions meshroom/nodes/aliceVision/ApplyCalibration.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
__version__ = "1.0"

from meshroom.core import desc

class ApplyCalibration(desc.AVCommandLineNode):
commandLine = 'aliceVision_applyCalibration {allParams}'
size = desc.DynamicNodeSize('input')

category = 'Utils'
documentation = '''
Overwrite intrinsics with a calibrated intrinsic.
'''

inputs = [
desc.File(
name='input',
label='Input SfMData',
description='SfMData file.',
value='',
uid=[0],
),
desc.File(
name='calibration',
label='Calibration',
description='Calibration SfMData file.',
value='',
uid=[0],
),
]

outputs = [
desc.File(
name='output',
label='SfMData File',
description='Path to the output SfMData file.',
value=desc.Node.internalFolder + 'sfmData.sfm',
uid=[],
),
]
27 changes: 25 additions & 2 deletions meshroom/nodes/aliceVision/CameraInit.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,23 @@
name="distortionParams",
elementDesc=desc.FloatParam(name="p", label="", description="", value=0.0, uid=[0], range=(-0.1, 0.1, 0.01)),
label="Distortion Params",
description="Distortion Parameters",
description="Distortion parameters.",
),
desc.GroupAttribute(
name="undistortionOffset",
label="Undistortion Offset",
description="Undistortion offset.",
groupDesc=[
desc.FloatParam(name="x", label="x", description="", value=0.0, uid=[0], range=(0.0, 10000.0, 1.0)),
desc.FloatParam(name="y", label="y", description="", value=0.0, uid=[0], range=(0.0, 10000.0, 1.0)),
]
),
desc.ListAttribute(
name="undistortionParams",
elementDesc=desc.FloatParam(name="p", label="", description="", value=0.0, uid=[0], range=(-0.1, 0.1, 0.01)),
label="Undistortion Params",
description="Undistortion parameters."
),

desc.BoolParam(name='locked', label='Locked',
description='If the camera has been calibrated, the internal camera parameters (intrinsics) can be locked. It should improve robustness and speedup the reconstruction.',
value=False, uid=[0]),
Expand Down Expand Up @@ -123,6 +137,14 @@ def readSfMData(sfmFile):
if intrinsic['distortionParams'] == '':
intrinsic['distortionParams'] = list()

offset = intrinsic['undistortionOffset']
intrinsic['undistortionOffset'] = {}
intrinsic['undistortionOffset']['x'] = offset[0]
intrinsic['undistortionOffset']['y'] = offset[1]

if intrinsic['undistortionParams'] == '':
intrinsic['undistortionParams'] = list()

viewsKeys = [v.name for v in Viewpoint]
views = [{k: v for k, v in item.items() if k in viewsKeys} for item in data.get("views", [])]
for view in views:
Expand Down Expand Up @@ -411,6 +433,7 @@ def createViewpointsFile(self, node, additionalViews=()):
intrinsics = node.intrinsics.getPrimitiveValue(exportDefault=True)
for intrinsic in intrinsics:
intrinsic['principalPoint'] = [intrinsic['principalPoint']['x'], intrinsic['principalPoint']['y']]
intrinsic['undistortionOffset'] = [intrinsic['undistortionOffset']['x'], intrinsic['undistortionOffset']['y']]
views = node.viewpoints.getPrimitiveValue(exportDefault=False)

# convert the metadata string into a map
Expand Down
44 changes: 20 additions & 24 deletions meshroom/nodes/aliceVision/DistortionCalibration.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
__version__ = '2.0'
__version__ = '3.0'

from meshroom.core import desc

Expand All @@ -7,46 +7,42 @@ class DistortionCalibration(desc.AVCommandLineNode):
commandLine = 'aliceVision_distortionCalibration {allParams}'
size = desc.DynamicNodeSize('input')

category = 'Other'
documentation = '''
Calibration of a camera/lens couple distortion using a full screen checkerboard
Calibration of a camera/lens couple distortion using a full screen checkerboard.
'''

inputs = [
desc.File(
name='input',
label='SfmData',
description='SfmData File',
label='Input SfMData',
description='SfMData file.',
value='',
uid=[0],
),
desc.ListAttribute(
elementDesc=desc.File(
name='lensGridImage',
label='Lens Grid Image',
description='',
value='',
uid=[0],
),
name='lensGrid',
label='Lens Grid Images',
description='Lens grid images to estimate the optical distortions.',
desc.File(
name='checkerboards',
label='Checkerboards Folder',
description='Folder containing checkerboard JSON files.',
value='',
uid=[0],
),
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'],
name='cameraModel',
label='Camera Model',
description='Camera model used to estimate distortion.',
value='3deanamorphic4',
values=['3deanamorphic4'],
exclusive=True,
uid=[],
uid=[0],
),
]

outputs = [
desc.File(
name='outSfMData',
label='SfmData File',
description='Path to the output sfmData file',
name='output',
label='SfMData File',
description='Path to the output SfMData file.',
value=desc.Node.internalFolder + 'sfmData.sfm',
uid=[],
)
Expand Down
49 changes: 49 additions & 0 deletions meshroom/nodes/aliceVision/ExportDistortion.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
__version__ = "1.0"

from meshroom.core import desc

class ExportDistortion(desc.AVCommandLineNode):
commandLine = 'aliceVision_exportDistortion {allParams}'

category = 'Export'
documentation = '''
Export the distortion model and parameters of cameras in a SfM scene.
'''

inputs = [
desc.File(
name='input',
label='Input SfMData',
description='SfMData file.',
value='',
uid=[0],
),
]

outputs = [
desc.File(
name='output',
label='Folder',
description='Output folder.',
value=desc.Node.internalFolder,
uid=[],
),
desc.File(
name='distoStMap',
label='Distortion ST Map',
description='Calibrated distortion ST map.',
semantic='image',
value=desc.Node.internalFolder + '<INTRINSIC_ID>_distort.exr',
group='', # do not export on the command line
uid=[],
),
desc.File(
name='undistoStMap',
label='Undistortion ST Map',
description='Calibrated undistortion ST map.',
semantic='image',
value=desc.Node.internalFolder + '<INTRINSIC_ID>_undistort.exr',
group='', # do not export on the command line
uid=[],
),
]
135 changes: 62 additions & 73 deletions meshroom/pipelines/cameraTracking.mg
Original file line number Diff line number Diff line change
@@ -1,105 +1,94 @@
{
"header": {
"pipelineVersion": "2.2",
"releaseVersion": "2023.1.0",
"fileVersion": "1.1",
"template": true,
"pipelineVersion": "2.2",
"releaseVersion": "2023.2.0-develop",
"fileVersion": "1.1",
"template": true,
"nodesVersions": {
"ExportAnimatedCamera": "2.0",
"FeatureMatching": "2.0",
"DistortionCalibration": "2.0",
"CameraInit": "9.0",
"ImageMatching": "2.0",
"FeatureExtraction": "1.1",
"ExportAnimatedCamera": "2.0",
"Publish": "1.2",
"StructureFromMotion": "3.0",
"Publish": "1.2"
"FeatureExtraction": "1.1",
"FeatureMatching": "2.0",
"CameraInit": "9.0",
"ImageMatching": "2.0"
}
},
},
"graph": {
"DistortionCalibration_1": {
"inputs": {
"input": "{CameraInit_1.output}"
},
"nodeType": "DistortionCalibration",
"position": [
200,
160
]
},
"ImageMatching_1": {
"nodeType": "ImageMatching",
"position": [
400,
0
],
"inputs": {
"nbNeighbors": 10,
"nbMatches": 5,
"input": "{FeatureExtraction_1.input}",
"input": "{FeatureExtraction_1.input}",
"featuresFolders": [
"{FeatureExtraction_1.output}"
]
},
"nodeType": "ImageMatching",
],
"nbMatches": 5,
"nbNeighbors": 10
}
},
"FeatureExtraction_1": {
"nodeType": "FeatureExtraction",
"position": [
400,
200,
0
]
},
"FeatureExtraction_1": {
],
"inputs": {
"input": "{CameraInit_1.output}"
},
"nodeType": "FeatureExtraction",
}
},
"StructureFromMotion_1": {
"nodeType": "StructureFromMotion",
"position": [
200,
800,
0
]
},
"StructureFromMotion_1": {
],
"inputs": {
"minAngleForLandmark": 0.5,
"minNumberOfObservationsForTriangulation": 3,
"describerTypes": "{FeatureMatching_1.describerTypes}",
"input": "{FeatureMatching_1.input}",
"featuresFolders": "{FeatureMatching_1.featuresFolders}",
"input": "{FeatureMatching_1.input}",
"featuresFolders": "{FeatureMatching_1.featuresFolders}",
"matchesFolders": [
"{FeatureMatching_1.output}"
],
"minInputTrackLength": 5,
"minAngleForTriangulation": 1.0
},
"nodeType": "StructureFromMotion",
],
"describerTypes": "{FeatureMatching_1.describerTypes}",
"minInputTrackLength": 5,
"minNumberOfObservationsForTriangulation": 3,
"minAngleForTriangulation": 1.0,
"minAngleForLandmark": 0.5
}
},
"ExportAnimatedCamera_1": {
"nodeType": "ExportAnimatedCamera",
"position": [
800,
1000,
0
]
},
"ExportAnimatedCamera_1": {
],
"inputs": {
"input": "{StructureFromMotion_1.output}"
},
"nodeType": "ExportAnimatedCamera",
"position": [
1000,
0
]
},
}
},
"CameraInit_1": {
"inputs": {},
"nodeType": "CameraInit",
"nodeType": "CameraInit",
"position": [
0,
0,
0
]
},
],
"inputs": {}
},
"FeatureMatching_1": {
"inputs": {
"describerTypes": "{FeatureExtraction_1.describerTypes}",
"imagePairsList": "{ImageMatching_1.output}",
"input": "{DistortionCalibration_1.outSfMData}",
"featuresFolders": "{ImageMatching_1.featuresFolders}"
},
"nodeType": "FeatureMatching",
"nodeType": "FeatureMatching",
"position": [
600,
600,
0
]
],
"inputs": {
"input": "{ImageMatching_1.input}",
"featuresFolders": "{ImageMatching_1.featuresFolders}",
"imagePairsList": "{ImageMatching_1.output}",
"describerTypes": "{FeatureExtraction_1.describerTypes}"
}
},
"Publish_1": {
"nodeType": "Publish",
Expand Down
Loading