From 15414c198413c34f543aa0ae5f8110d0b0c26107 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Candice=20Bent=C3=A9jac?= Date: Mon, 17 Mar 2025 12:29:37 +0100 Subject: [PATCH 1/9] Remove all default templates from Meshroom These templates are moved to AliceVision's repository. --- meshroom/pipelines/cameraTracking.mg | 531 ------------- .../pipelines/cameraTrackingExperimental.mg | 596 --------------- .../cameraTrackingWithoutCalibration.mg | 502 ------------ ...aTrackingWithoutCalibrationExperimental.mg | 567 -------------- meshroom/pipelines/distortionCalibration.mg | 69 -- meshroom/pipelines/hdrFusion.mg | 77 -- .../pipelines/multi-viewPhotometricStereo.mg | 277 ------- meshroom/pipelines/nodalCameraTracking.mg | 293 ------- .../nodalCameraTrackingWithoutCalibration.mg | 250 ------ meshroom/pipelines/panoramaFisheyeHdr.mg | 238 ------ meshroom/pipelines/panoramaHdr.mg | 233 ------ meshroom/pipelines/photogrammetry.mg | 161 ---- .../photogrammetryAndCameraTracking.mg | 605 --------------- ...ogrammetryAndCameraTrackingExperimental.mg | 712 ------------------ meshroom/pipelines/photogrammetryDraft.mg | 136 ---- .../pipelines/photogrammetryExperimental.mg | 200 ----- meshroom/pipelines/photometricStereo.mg | 77 -- 17 files changed, 5524 deletions(-) delete mode 100644 meshroom/pipelines/cameraTracking.mg delete mode 100644 meshroom/pipelines/cameraTrackingExperimental.mg delete mode 100644 meshroom/pipelines/cameraTrackingWithoutCalibration.mg delete mode 100644 meshroom/pipelines/cameraTrackingWithoutCalibrationExperimental.mg delete mode 100644 meshroom/pipelines/distortionCalibration.mg delete mode 100644 meshroom/pipelines/hdrFusion.mg delete mode 100644 meshroom/pipelines/multi-viewPhotometricStereo.mg delete mode 100644 meshroom/pipelines/nodalCameraTracking.mg delete mode 100644 meshroom/pipelines/nodalCameraTrackingWithoutCalibration.mg delete mode 100644 meshroom/pipelines/panoramaFisheyeHdr.mg delete mode 100644 meshroom/pipelines/panoramaHdr.mg delete mode 100644 meshroom/pipelines/photogrammetry.mg delete mode 100644 meshroom/pipelines/photogrammetryAndCameraTracking.mg delete mode 100644 meshroom/pipelines/photogrammetryAndCameraTrackingExperimental.mg delete mode 100644 meshroom/pipelines/photogrammetryDraft.mg delete mode 100644 meshroom/pipelines/photogrammetryExperimental.mg delete mode 100644 meshroom/pipelines/photometricStereo.mg diff --git a/meshroom/pipelines/cameraTracking.mg b/meshroom/pipelines/cameraTracking.mg deleted file mode 100644 index 6fcf26ae85..0000000000 --- a/meshroom/pipelines/cameraTracking.mg +++ /dev/null @@ -1,531 +0,0 @@ -{ - "header": { - "releaseVersion": "2025.1.0-develop", - "fileVersion": "2.0", - "template": true, - "nodesVersions": { - "ApplyCalibration": "1.0", - "CameraInit": "12.0", - "CheckerboardDetection": "1.0", - "ConvertSfMFormat": "2.0", - "DepthMap": "5.0", - "DepthMapFilter": "4.0", - "DistortionCalibration": "5.0", - "ExportAnimatedCamera": "2.0", - "ExportDistortion": "2.0", - "FeatureExtraction": "1.3", - "FeatureMatching": "2.0", - "ImageDetectionPrompt": "0.1", - "ImageMatching": "2.0", - "ImageMatchingMultiSfM": "1.0", - "ImageSegmentationBox": "0.1", - "KeyframeSelection": "5.0", - "MeshDecimate": "1.0", - "MeshFiltering": "3.0", - "Meshing": "7.0", - "PrepareDenseScene": "3.1", - "Publish": "1.3", - "ScenePreview": "2.0", - "SfMTransfer": "2.1", - "SfMTriangulation": "1.0", - "StructureFromMotion": "3.3", - "Texturing": "6.0" - } - }, - "graph": { - "ApplyCalibration_1": { - "nodeType": "ApplyCalibration", - "position": [ - 0, - 0 - ], - "inputs": { - "input": "{CameraInit_1.output}", - "calibration": "{DistortionCalibration_1.output}" - }, - "internalInputs": { - "color": "#575963" - } - }, - "CameraInit_1": { - "nodeType": "CameraInit", - "position": [ - -200, - 0 - ], - "inputs": {}, - "internalInputs": { - "color": "#575963" - } - }, - "CameraInit_2": { - "nodeType": "CameraInit", - "position": [ - -600, - -160 - ], - "inputs": {}, - "internalInputs": { - "label": "CameraInitLensGrid", - "color": "#302e2e" - } - }, - "CheckerboardDetection_1": { - "nodeType": "CheckerboardDetection", - "position": [ - -400, - -160 - ], - "inputs": { - "input": "{CameraInit_2.output}", - "useNestedGrids": true, - "exportDebugImages": true - }, - "internalInputs": { - "color": "#302e2e" - } - }, - "ConvertSfMFormat_1": { - "nodeType": "ConvertSfMFormat", - "position": [ - 3000, - 200 - ], - "inputs": { - "input": "{ExportAnimatedCamera_1.input}", - "fileExt": "json", - "describerTypes": "{StructureFromMotion_1.describerTypes}", - "structure": false, - "observations": false - }, - "internalInputs": { - "color": "#4c594c" - } - }, - "DepthMapFilter_1": { - "nodeType": "DepthMapFilter", - "position": [ - 2400, - 0 - ], - "inputs": { - "input": "{DepthMap_1.input}", - "depthMapsFolder": "{DepthMap_1.output}" - }, - "internalInputs": { - "color": "#3f3138" - } - }, - "DepthMap_1": { - "nodeType": "DepthMap", - "position": [ - 2200, - 0 - ], - "inputs": { - "input": "{PrepareDenseScene_1.input}", - "imagesFolder": "{PrepareDenseScene_1.output}", - "downscale": 1 - }, - "internalInputs": { - "color": "#3f3138" - } - }, - "DistortionCalibration_1": { - "nodeType": "DistortionCalibration", - "position": [ - -200, - -160 - ], - "inputs": { - "input": "{CheckerboardDetection_1.input}", - "checkerboards": "{CheckerboardDetection_1.output}" - }, - "internalInputs": { - "color": "#302e2e" - } - }, - "ExportAnimatedCamera_1": { - "nodeType": "ExportAnimatedCamera", - "position": [ - 1600, - 200 - ], - "inputs": { - "input": "{StructureFromMotion_1.output}", - "exportUndistortedImages": true - }, - "internalInputs": { - "color": "#80766f" - } - }, - "ExportDistortion_1": { - "nodeType": "ExportDistortion", - "position": [ - 0, - -160 - ], - "inputs": { - "input": "{DistortionCalibration_1.output}" - }, - "internalInputs": { - "color": "#302e2e" - } - }, - "FeatureExtraction_1": { - "nodeType": "FeatureExtraction", - "position": [ - 400, - 200 - ], - "inputs": { - "input": "{ApplyCalibration_1.output}", - "masksFolder": "{ImageSegmentationBox_1.output}", - "maskExtension": "exr" - }, - "internalInputs": { - "color": "#575963" - } - }, - "FeatureMatching_1": { - "nodeType": "FeatureMatching", - "position": [ - 600, - 0 - ], - "inputs": { - "input": "{ImageMatching_1.input}", - "featuresFolders": "{ImageMatching_1.featuresFolders}", - "imagePairsList": "{ImageMatching_1.output}", - "describerTypes": "{FeatureExtraction_1.describerTypes}" - }, - "internalInputs": { - "label": "FeatureMatchingKeyframes", - "color": "#575963" - } - }, - "FeatureMatching_2": { - "nodeType": "FeatureMatching", - "position": [ - 1200, - 360 - ], - "inputs": { - "input": "{ImageMatching_2.input}", - "featuresFolders": "{ImageMatching_2.featuresFolders}", - "imagePairsList": "{ImageMatching_2.output}" - }, - "internalInputs": { - "label": "FeatureMatchingAllFrames", - "color": "#80766f" - } - }, - "FeatureMatching_3": { - "nodeType": "FeatureMatching", - "position": [ - 1200, - 200 - ], - "inputs": { - "input": "{ImageMatchingMultiSfM_1.outputCombinedSfM}", - "featuresFolders": "{ImageMatchingMultiSfM_1.featuresFolders}", - "imagePairsList": "{ImageMatchingMultiSfM_1.output}", - "describerTypes": "{FeatureExtraction_1.describerTypes}" - }, - "internalInputs": { - "label": "FeatureMatchingFramesToKeyframes", - "color": "#80766f" - } - }, - "ImageDetectionPrompt_1": { - "nodeType": "ImageDetectionPrompt", - "position": [ - 0, - 200 - ], - "inputs": { - "input": "{CameraInit_1.output}" - }, - "internalInputs": { - "color": "#575963" - } - }, - "ImageMatchingMultiSfM_1": { - "nodeType": "ImageMatchingMultiSfM", - "position": [ - 1000, - 200 - ], - "inputs": { - "input": "{KeyframeSelection_1.outputSfMDataFrames}", - "inputB": "{StructureFromMotion_2.output}", - "featuresFolders": [ - "{FeatureExtraction_1.output}" - ], - "method": "VocabularyTree", - "matchingMode": "a/b", - "nbMatches": 20 - }, - "internalInputs": { - "color": "#80766f" - } - }, - "ImageMatching_1": { - "nodeType": "ImageMatching", - "position": [ - 400, - 0 - ], - "inputs": { - "input": "{KeyframeSelection_1.outputSfMDataKeyframes}", - "featuresFolders": [ - "{FeatureExtraction_1.output}" - ], - "method": "Exhaustive" - }, - "internalInputs": { - "label": "ImageMatchingKeyframes", - "color": "#575963" - } - }, - "ImageMatching_2": { - "nodeType": "ImageMatching", - "position": [ - 1000, - 360 - ], - "inputs": { - "input": "{ApplyCalibration_1.output}", - "featuresFolders": [ - "{FeatureExtraction_1.output}" - ], - "method": "Sequential", - "nbNeighbors": 20 - }, - "internalInputs": { - "color": "#80766f" - } - }, - "ImageSegmentationBox_1": { - "nodeType": "ImageSegmentationBox", - "position": [ - 200, - 200 - ], - "inputs": { - "input": "{ImageDetectionPrompt_1.input}", - "bboxFolder": "{ImageDetectionPrompt_1.output}", - "maskInvert": true, - "keepFilename": true - }, - "internalInputs": { - "color": "#575963" - } - }, - "KeyframeSelection_1": { - "nodeType": "KeyframeSelection", - "position": [ - 200, - 0 - ], - "inputs": { - "inputPaths": [ - "{ApplyCalibration_1.output}" - ] - }, - "internalInputs": { - "color": "#575963" - } - }, - "MeshDecimate_1": { - "nodeType": "MeshDecimate", - "position": [ - 3000, - 0 - ], - "inputs": { - "input": "{MeshFiltering_1.outputMesh}", - "simplificationFactor": 0.05 - }, - "internalInputs": { - "color": "#3f3138" - } - }, - "MeshFiltering_1": { - "nodeType": "MeshFiltering", - "position": [ - 2800, - 0 - ], - "inputs": { - "inputMesh": "{Meshing_1.outputMesh}", - "filterLargeTrianglesFactor": 10.0 - }, - "internalInputs": { - "color": "#3f3138" - } - }, - "Meshing_1": { - "nodeType": "Meshing", - "position": [ - 2600, - 0 - ], - "inputs": { - "input": "{DepthMapFilter_1.input}", - "depthMapsFolder": "{DepthMapFilter_1.output}", - "estimateSpaceFromSfM": false, - "minStep": 1, - "fullWeight": 10.0, - "saveRawDensePointCloud": true - }, - "internalInputs": { - "color": "#3f3138" - } - }, - "PrepareDenseScene_1": { - "nodeType": "PrepareDenseScene", - "position": [ - 2000, - 0 - ], - "inputs": { - "input": "{SfMTriangulation_1.output}", - "maskExtension": "exr" - }, - "internalInputs": { - "color": "#3f3138" - } - }, - "Publish_1": { - "nodeType": "Publish", - "position": [ - 3600, - 100 - ], - "inputs": { - "inputFiles": [ - "{ExportAnimatedCamera_1.output}", - "{Texturing_1.output}", - "{ScenePreview_1.output}", - "{ExportDistortion_1.output}" - ] - } - }, - "ScenePreview_1": { - "nodeType": "ScenePreview", - "position": [ - 3200, - 200 - ], - "inputs": { - "cameras": "{ConvertSfMFormat_1.output}", - "model": "{MeshDecimate_1.output}", - "undistortedImages": "{ExportAnimatedCamera_1.outputUndistorted}", - "masks": "{ImageSegmentationBox_1.output}" - }, - "internalInputs": { - "color": "#4c594c" - } - }, - "SfMTransfer_1": { - "nodeType": "SfMTransfer", - "position": [ - 1600, - 0 - ], - "inputs": { - "input": "{KeyframeSelection_1.outputSfMDataKeyframes}", - "reference": "{StructureFromMotion_1.output}", - "transferLandmarks": false - }, - "internalInputs": { - "comment": "Transfer pose from final camera tracking into the keyframes-only scene.", - "color": "#3f3138" - } - }, - "SfMTriangulation_1": { - "nodeType": "SfMTriangulation", - "position": [ - 1800, - 0 - ], - "inputs": { - "input": "{SfMTransfer_1.output}", - "featuresFolders": "{StructureFromMotion_2.featuresFolders}", - "matchesFolders": "{StructureFromMotion_2.matchesFolders}", - "minAngleForTriangulation": 1.0, - "minAngleForLandmark": 0.5 - }, - "internalInputs": { - "color": "#3f3138" - } - }, - "StructureFromMotion_1": { - "nodeType": "StructureFromMotion", - "position": [ - 1400, - 200 - ], - "inputs": { - "input": "{FeatureMatching_3.input}", - "featuresFolders": "{FeatureMatching_3.featuresFolders}", - "matchesFolders": [ - "{FeatureMatching_3.output}", - "{FeatureMatching_2.output}" - ], - "describerTypes": "{FeatureMatching_3.describerTypes}", - "nbFirstUnstableCameras": 0, - "maxImagesPerGroup": 0, - "bundleAdjustmentMaxOutliers": -1, - "minInputTrackLength": 5, - "minNumberOfObservationsForTriangulation": 3, - "minAngleForTriangulation": 1.0, - "minAngleForLandmark": 0.5, - "filterTrackForks": true - }, - "internalInputs": { - "comment": "Estimate cameras parameters for the complete camera tracking sequence.", - "color": "#80766f" - } - }, - "StructureFromMotion_2": { - "nodeType": "StructureFromMotion", - "position": [ - 800, - 0 - ], - "inputs": { - "input": "{FeatureMatching_1.input}", - "featuresFolders": "{FeatureMatching_1.featuresFolders}", - "matchesFolders": [ - "{FeatureMatching_1.output}" - ], - "describerTypes": "{FeatureMatching_1.describerTypes}", - "minAngleForTriangulation": 1.0, - "minAngleForLandmark": 0.5, - "filterTrackForks": true - }, - "internalInputs": { - "comment": "Solve all keyframes first.", - "label": "StructureFromMotionKeyframes", - "color": "#575963" - } - }, - "Texturing_1": { - "nodeType": "Texturing", - "position": [ - 3200, - 0 - ], - "inputs": { - "input": "{Meshing_1.output}", - "imagesFolder": "{PrepareDenseScene_1.output}", - "inputMesh": "{MeshDecimate_1.output}" - }, - "internalInputs": { - "color": "#3f3138" - } - } - } -} \ No newline at end of file diff --git a/meshroom/pipelines/cameraTrackingExperimental.mg b/meshroom/pipelines/cameraTrackingExperimental.mg deleted file mode 100644 index 25b3e9e630..0000000000 --- a/meshroom/pipelines/cameraTrackingExperimental.mg +++ /dev/null @@ -1,596 +0,0 @@ -{ - "header": { - "releaseVersion": "2025.1.0-develop", - "fileVersion": "2.0", - "nodesVersions": { - "ApplyCalibration": "1.0", - "CameraInit": "12.0", - "CheckerboardDetection": "1.0", - "ConvertSfMFormat": "2.0", - "DepthMap": "5.0", - "DepthMapFilter": "4.0", - "DistortionCalibration": "5.0", - "ExportAnimatedCamera": "2.0", - "ExportDistortion": "2.0", - "FeatureExtraction": "1.3", - "FeatureMatching": "2.0", - "ImageDetectionPrompt": "0.1", - "ImageMatching": "2.0", - "ImageMatchingMultiSfM": "1.0", - "ImageSegmentationBox": "0.1", - "KeyframeSelection": "5.0", - "MeshDecimate": "1.0", - "MeshFiltering": "3.0", - "Meshing": "7.0", - "PrepareDenseScene": "3.1", - "Publish": "1.3", - "RelativePoseEstimating": "3.0", - "ScenePreview": "2.0", - "SfMBootStraping": "3.0", - "SfMExpanding": "2.0", - "SfMTransfer": "2.1", - "SfMTriangulation": "1.0", - "Texturing": "6.0", - "TracksBuilding": "1.0" - }, - "template": true - }, - "graph": { - "ApplyCalibration_1": { - "nodeType": "ApplyCalibration", - "position": [ - 0, - 0 - ], - "inputs": { - "input": "{CameraInit_1.output}", - "calibration": "{DistortionCalibration_1.output}" - }, - "internalInputs": { - "color": "#575963" - } - }, - "CameraInit_1": { - "nodeType": "CameraInit", - "position": [ - -200, - 0 - ], - "inputs": {}, - "internalInputs": { - "color": "#575963" - } - }, - "CameraInit_2": { - "nodeType": "CameraInit", - "position": [ - -600, - -160 - ], - "inputs": {}, - "internalInputs": { - "label": "CameraInitLensGrid", - "color": "#302e2e" - } - }, - "CheckerboardDetection_1": { - "nodeType": "CheckerboardDetection", - "position": [ - -400, - -160 - ], - "inputs": { - "input": "{CameraInit_2.output}", - "useNestedGrids": true, - "exportDebugImages": true - }, - "internalInputs": { - "color": "#302e2e" - } - }, - "ConvertSfMFormat_1": { - "nodeType": "ConvertSfMFormat", - "position": [ - 3800, - 200 - ], - "inputs": { - "input": "{ExportAnimatedCamera_1.input}", - "fileExt": "json", - "describerTypes": "{TracksBuilding_2.describerTypes}", - "structure": false, - "observations": false - }, - "internalInputs": { - "color": "#4c594c" - } - }, - "DepthMapFilter_1": { - "nodeType": "DepthMapFilter", - "position": [ - 3200, - 0 - ], - "inputs": { - "input": "{DepthMap_1.input}", - "depthMapsFolder": "{DepthMap_1.output}" - }, - "internalInputs": { - "color": "#3f3138" - } - }, - "DepthMap_1": { - "nodeType": "DepthMap", - "position": [ - 3000, - 0 - ], - "inputs": { - "input": "{PrepareDenseScene_1.input}", - "imagesFolder": "{PrepareDenseScene_1.output}", - "downscale": 1 - }, - "internalInputs": { - "color": "#3f3138" - } - }, - "DistortionCalibration_1": { - "nodeType": "DistortionCalibration", - "position": [ - -200, - -160 - ], - "inputs": { - "input": "{CheckerboardDetection_1.input}", - "checkerboards": "{CheckerboardDetection_1.output}" - }, - "internalInputs": { - "color": "#302e2e" - } - }, - "ExportAnimatedCamera_1": { - "nodeType": "ExportAnimatedCamera", - "position": [ - 2400, - 200 - ], - "inputs": { - "input": "{SfMExpanding_2.output}", - "exportUndistortedImages": true - }, - "internalInputs": { - "color": "#80766f" - } - }, - "ExportDistortion_1": { - "nodeType": "ExportDistortion", - "position": [ - 0, - -160 - ], - "inputs": { - "input": "{DistortionCalibration_1.output}" - }, - "internalInputs": { - "color": "#302e2e" - } - }, - "FeatureExtraction_1": { - "nodeType": "FeatureExtraction", - "position": [ - 400, - 200 - ], - "inputs": { - "input": "{ApplyCalibration_1.output}", - "masksFolder": "{ImageSegmentationBox_1.output}", - "maskExtension": "exr" - }, - "internalInputs": { - "color": "#575963" - } - }, - "FeatureMatching_1": { - "nodeType": "FeatureMatching", - "position": [ - 600, - 0 - ], - "inputs": { - "input": "{ImageMatching_1.input}", - "featuresFolders": "{ImageMatching_1.featuresFolders}", - "imagePairsList": "{ImageMatching_1.output}", - "describerTypes": "{FeatureExtraction_1.describerTypes}" - }, - "internalInputs": { - "label": "FeatureMatchingKeyframes", - "color": "#575963" - } - }, - "FeatureMatching_2": { - "nodeType": "FeatureMatching", - "position": [ - 1800, - 400 - ], - "inputs": { - "input": "{ImageMatching_2.input}", - "featuresFolders": "{ImageMatching_2.featuresFolders}", - "imagePairsList": "{ImageMatching_2.output}" - }, - "internalInputs": { - "label": "FeatureMatchingAllFrames", - "color": "#80766f" - } - }, - "FeatureMatching_3": { - "nodeType": "FeatureMatching", - "position": [ - 1800, - 200 - ], - "inputs": { - "input": "{ImageMatchingMultiSfM_1.outputCombinedSfM}", - "featuresFolders": "{ImageMatchingMultiSfM_1.featuresFolders}", - "imagePairsList": "{ImageMatchingMultiSfM_1.output}", - "describerTypes": "{FeatureExtraction_1.describerTypes}" - }, - "internalInputs": { - "label": "FeatureMatchingFramesToKeyframes", - "color": "#80766f" - } - }, - "ImageDetectionPrompt_1": { - "nodeType": "ImageDetectionPrompt", - "position": [ - 0, - 200 - ], - "inputs": { - "input": "{CameraInit_1.output}" - }, - "internalInputs": { - "color": "#575963" - } - }, - "ImageMatchingMultiSfM_1": { - "nodeType": "ImageMatchingMultiSfM", - "position": [ - 1600, - 200 - ], - "inputs": { - "input": "{KeyframeSelection_1.outputSfMDataFrames}", - "inputB": "{SfMExpanding_1.output}", - "featuresFolders": [ - "{FeatureExtraction_1.output}" - ], - "method": "VocabularyTree", - "matchingMode": "a/b", - "nbMatches": 20 - }, - "internalInputs": { - "color": "#80766f" - } - }, - "ImageMatching_1": { - "nodeType": "ImageMatching", - "position": [ - 400, - 0 - ], - "inputs": { - "input": "{KeyframeSelection_1.outputSfMDataKeyframes}", - "featuresFolders": [ - "{FeatureExtraction_1.output}" - ], - "method": "Exhaustive" - }, - "internalInputs": { - "label": "ImageMatchingKeyframes", - "color": "#575963" - } - }, - "ImageMatching_2": { - "nodeType": "ImageMatching", - "position": [ - 1600, - 400 - ], - "inputs": { - "input": "{ApplyCalibration_1.output}", - "featuresFolders": [ - "{FeatureExtraction_1.output}" - ], - "method": "Sequential", - "nbNeighbors": 20 - }, - "internalInputs": { - "color": "#80766f" - } - }, - "ImageSegmentationBox_1": { - "nodeType": "ImageSegmentationBox", - "position": [ - 200, - 200 - ], - "inputs": { - "input": "{ImageDetectionPrompt_1.input}", - "bboxFolder": "{ImageDetectionPrompt_1.output}", - "maskInvert": true, - "keepFilename": true - }, - "internalInputs": { - "color": "#575963" - } - }, - "KeyframeSelection_1": { - "nodeType": "KeyframeSelection", - "position": [ - 200, - 0 - ], - "inputs": { - "inputPaths": [ - "{ApplyCalibration_1.output}" - ] - }, - "internalInputs": { - "color": "#575963" - } - }, - "MeshDecimate_1": { - "nodeType": "MeshDecimate", - "position": [ - 3800, - 0 - ], - "inputs": { - "input": "{MeshFiltering_1.outputMesh}", - "simplificationFactor": 0.05 - }, - "internalInputs": { - "color": "#3f3138" - } - }, - "MeshFiltering_1": { - "nodeType": "MeshFiltering", - "position": [ - 3600, - 0 - ], - "inputs": { - "inputMesh": "{Meshing_1.outputMesh}", - "filterLargeTrianglesFactor": 10.0 - }, - "internalInputs": { - "color": "#3f3138" - } - }, - "Meshing_1": { - "nodeType": "Meshing", - "position": [ - 3400, - 0 - ], - "inputs": { - "input": "{DepthMapFilter_1.input}", - "depthMapsFolder": "{DepthMapFilter_1.output}", - "estimateSpaceFromSfM": false, - "minStep": 1, - "fullWeight": 10.0, - "saveRawDensePointCloud": true - }, - "internalInputs": { - "color": "#3f3138" - } - }, - "PrepareDenseScene_1": { - "nodeType": "PrepareDenseScene", - "position": [ - 2800, - 0 - ], - "inputs": { - "input": "{SfMTriangulation_1.output}", - "maskExtension": "exr" - }, - "internalInputs": { - "color": "#3f3138" - } - }, - "Publish_1": { - "nodeType": "Publish", - "position": [ - 4200, - 100 - ], - "inputs": { - "inputFiles": [ - "{ExportAnimatedCamera_1.output}", - "{Texturing_1.output}", - "{ScenePreview_1.output}", - "{ExportDistortion_1.output}" - ] - } - }, - "RelativePoseEstimating_1": { - "nodeType": "RelativePoseEstimating", - "position": [ - 1000, - 0 - ], - "inputs": { - "input": "{TracksBuilding_1.input}", - "tracksFilename": "{TracksBuilding_1.output}", - "countIterations": 50000, - "minInliers": 100 - }, - "internalInputs": { - "color": "#575963" - } - }, - "ScenePreview_1": { - "nodeType": "ScenePreview", - "position": [ - 4000, - 200 - ], - "inputs": { - "cameras": "{ConvertSfMFormat_1.output}", - "model": "{MeshDecimate_1.output}", - "undistortedImages": "{ExportAnimatedCamera_1.outputUndistorted}", - "masks": "{ImageSegmentationBox_1.output}" - }, - "internalInputs": { - "color": "#4c594c" - } - }, - "SfMBootStraping_1": { - "nodeType": "SfMBootStraping", - "position": [ - 1200, - 0 - ], - "inputs": { - "input": "{RelativePoseEstimating_1.input}", - "tracksFilename": "{RelativePoseEstimating_1.tracksFilename}", - "pairs": "{RelativePoseEstimating_1.output}" - }, - "internalInputs": { - "color": "#575963" - } - }, - "SfMExpanding_1": { - "nodeType": "SfMExpanding", - "position": [ - 1400, - 0 - ], - "inputs": { - "input": "{SfMBootStraping_1.output}", - "tracksFilename": "{SfMBootStraping_1.tracksFilename}", - "meshFilename": "{SfMBootStraping_1.meshFilename}", - "minAngleForTriangulation": 1.0, - "minAngleForLandmark": 0.5 - }, - "internalInputs": { - "comment": "Estimate cameras parameters for the keyframes.", - "label": "SfMExpandingKeys", - "color": "#575963" - } - }, - "SfMExpanding_2": { - "nodeType": "SfMExpanding", - "position": [ - 2200, - 200 - ], - "inputs": { - "input": "{TracksBuilding_2.input}", - "tracksFilename": "{TracksBuilding_2.output}", - "meshFilename": "{SfMExpanding_1.meshFilename}", - "nbFirstUnstableCameras": 0, - "maxImagesPerGroup": 0, - "bundleAdjustmentMaxOutliers": 5000000, - "minNumberOfObservationsForTriangulation": 3, - "minAngleForTriangulation": 1.0, - "minAngleForLandmark": 0.5 - }, - "internalInputs": { - "comment": "Estimate cameras parameters for the complete camera tracking sequence.", - "label": "SfMExpandingAll", - "color": "#80766f" - } - }, - "SfMTransfer_1": { - "nodeType": "SfMTransfer", - "position": [ - 2400, - 0 - ], - "inputs": { - "input": "{KeyframeSelection_1.outputSfMDataKeyframes}", - "reference": "{SfMExpanding_2.output}", - "transferLandmarks": false - }, - "internalInputs": { - "comment": "Transfer pose from final camera tracking into the keyframes-only scene.", - "color": "#3f3138" - } - }, - "SfMTriangulation_1": { - "nodeType": "SfMTriangulation", - "position": [ - 2600, - 0 - ], - "inputs": { - "input": "{SfMTransfer_1.output}", - "featuresFolders": "{TracksBuilding_1.featuresFolders}", - "matchesFolders": "{TracksBuilding_1.matchesFolders}", - "minAngleForTriangulation": 1.0, - "minAngleForLandmark": 0.5 - }, - "internalInputs": { - "color": "#3f3138" - } - }, - "Texturing_1": { - "nodeType": "Texturing", - "position": [ - 4000, - 0 - ], - "inputs": { - "input": "{Meshing_1.output}", - "imagesFolder": "{PrepareDenseScene_1.output}", - "inputMesh": "{MeshDecimate_1.output}" - }, - "internalInputs": { - "color": "#3f3138" - } - }, - "TracksBuilding_1": { - "nodeType": "TracksBuilding", - "position": [ - 800, - 0 - ], - "inputs": { - "input": "{FeatureMatching_1.input}", - "featuresFolders": "{FeatureMatching_1.featuresFolders}", - "matchesFolders": [ - "{FeatureMatching_1.output}" - ], - "describerTypes": "{FeatureMatching_1.describerTypes}", - "filterTrackForks": true - }, - "internalInputs": { - "color": "#575963" - } - }, - "TracksBuilding_2": { - "nodeType": "TracksBuilding", - "position": [ - 2000, - 200 - ], - "inputs": { - "input": "{FeatureMatching_3.input}", - "featuresFolders": "{FeatureMatching_3.featuresFolders}", - "matchesFolders": [ - "{FeatureMatching_2.output}", - "{FeatureMatching_3.output}" - ], - "describerTypes": "{FeatureMatching_3.describerTypes}", - "minInputTrackLength": 5, - "filterTrackForks": true - }, - "internalInputs": { - "color": "#80766f" - } - } - } -} \ No newline at end of file diff --git a/meshroom/pipelines/cameraTrackingWithoutCalibration.mg b/meshroom/pipelines/cameraTrackingWithoutCalibration.mg deleted file mode 100644 index b34a7b9f2b..0000000000 --- a/meshroom/pipelines/cameraTrackingWithoutCalibration.mg +++ /dev/null @@ -1,502 +0,0 @@ -{ - "header": { - "releaseVersion": "2025.1.0-develop", - "fileVersion": "2.0", - "template": true, - "nodesVersions": { - "ApplyCalibration": "1.0", - "CameraInit": "12.0", - "ConvertDistortion": "1.0", - "ConvertSfMFormat": "2.0", - "DepthMap": "5.0", - "DepthMapFilter": "4.0", - "ExportAnimatedCamera": "2.0", - "ExportDistortion": "2.0", - "FeatureExtraction": "1.3", - "FeatureMatching": "2.0", - "ImageDetectionPrompt": "0.1", - "ImageMatching": "2.0", - "ImageMatchingMultiSfM": "1.0", - "ImageSegmentationBox": "0.1", - "KeyframeSelection": "5.0", - "MeshDecimate": "1.0", - "MeshFiltering": "3.0", - "Meshing": "7.0", - "PrepareDenseScene": "3.1", - "Publish": "1.3", - "ScenePreview": "2.0", - "SfMTransfer": "2.1", - "SfMTriangulation": "1.0", - "StructureFromMotion": "3.3", - "Texturing": "6.0" - } - }, - "graph": { - "ApplyCalibration_1": { - "nodeType": "ApplyCalibration", - "position": [ - 0, - 0 - ], - "inputs": { - "input": "{CameraInit_1.output}" - }, - "internalInputs": { - "color": "#575963" - } - }, - "CameraInit_1": { - "nodeType": "CameraInit", - "position": [ - -200, - 0 - ], - "inputs": {}, - "internalInputs": { - "color": "#575963" - } - }, - "ConvertDistortion_1": { - "nodeType": "ConvertDistortion", - "position": [ - 1600, - 360 - ], - "inputs": { - "input": "{StructureFromMotion_1.output}" - }, - "internalInputs": { - "color": "#80766f" - } - }, - "ConvertSfMFormat_1": { - "nodeType": "ConvertSfMFormat", - "position": [ - 3000, - 200 - ], - "inputs": { - "input": "{ExportAnimatedCamera_1.input}", - "fileExt": "json", - "describerTypes": "{StructureFromMotion_1.describerTypes}", - "structure": false, - "observations": false - }, - "internalInputs": { - "color": "#4c594c" - } - }, - "DepthMapFilter_1": { - "nodeType": "DepthMapFilter", - "position": [ - 2400, - 0 - ], - "inputs": { - "input": "{DepthMap_1.input}", - "depthMapsFolder": "{DepthMap_1.output}" - }, - "internalInputs": { - "color": "#3f3138" - } - }, - "DepthMap_1": { - "nodeType": "DepthMap", - "position": [ - 2200, - 0 - ], - "inputs": { - "input": "{PrepareDenseScene_1.input}", - "imagesFolder": "{PrepareDenseScene_1.output}", - "downscale": 1 - }, - "internalInputs": { - "color": "#3f3138" - } - }, - "ExportAnimatedCamera_1": { - "nodeType": "ExportAnimatedCamera", - "position": [ - 1600, - 200 - ], - "inputs": { - "input": "{StructureFromMotion_1.output}", - "exportUndistortedImages": true - }, - "internalInputs": { - "color": "#80766f" - } - }, - "ExportDistortion_1": { - "nodeType": "ExportDistortion", - "position": [ - 1800, - 360 - ], - "inputs": { - "input": "{ConvertDistortion_1.output}", - "exportLensGridsUndistorted": false - }, - "internalInputs": { - "color": "#80766f" - } - }, - "FeatureExtraction_1": { - "nodeType": "FeatureExtraction", - "position": [ - 400, - 200 - ], - "inputs": { - "input": "{ApplyCalibration_1.output}", - "masksFolder": "{ImageSegmentationBox_1.output}", - "maskExtension": "exr" - }, - "internalInputs": { - "color": "#575963" - } - }, - "FeatureMatching_1": { - "nodeType": "FeatureMatching", - "position": [ - 600, - 0 - ], - "inputs": { - "input": "{ImageMatching_1.input}", - "featuresFolders": "{ImageMatching_1.featuresFolders}", - "imagePairsList": "{ImageMatching_1.output}", - "describerTypes": "{FeatureExtraction_1.describerTypes}" - }, - "internalInputs": { - "label": "FeatureMatchingKeyframes", - "color": "#575963" - } - }, - "FeatureMatching_2": { - "nodeType": "FeatureMatching", - "position": [ - 1200, - 360 - ], - "inputs": { - "input": "{ImageMatching_2.input}", - "featuresFolders": "{ImageMatching_2.featuresFolders}", - "imagePairsList": "{ImageMatching_2.output}" - }, - "internalInputs": { - "label": "FeatureMatchingAllFrames", - "color": "#80766f" - } - }, - "FeatureMatching_3": { - "nodeType": "FeatureMatching", - "position": [ - 1200, - 200 - ], - "inputs": { - "input": "{ImageMatchingMultiSfM_1.outputCombinedSfM}", - "featuresFolders": "{ImageMatchingMultiSfM_1.featuresFolders}", - "imagePairsList": "{ImageMatchingMultiSfM_1.output}", - "describerTypes": "{FeatureExtraction_1.describerTypes}" - }, - "internalInputs": { - "label": "FeatureMatchingFramesToKeyframes", - "color": "#80766f" - } - }, - "ImageDetectionPrompt_1": { - "nodeType": "ImageDetectionPrompt", - "position": [ - 0, - 200 - ], - "inputs": { - "input": "{CameraInit_1.output}" - }, - "internalInputs": { - "color": "#575963" - } - }, - "ImageMatchingMultiSfM_1": { - "nodeType": "ImageMatchingMultiSfM", - "position": [ - 1000, - 200 - ], - "inputs": { - "input": "{KeyframeSelection_1.outputSfMDataFrames}", - "inputB": "{StructureFromMotion_2.output}", - "featuresFolders": [ - "{FeatureExtraction_1.output}" - ], - "method": "VocabularyTree", - "matchingMode": "a/b", - "nbMatches": 20 - }, - "internalInputs": { - "color": "#80766f" - } - }, - "ImageMatching_1": { - "nodeType": "ImageMatching", - "position": [ - 400, - 0 - ], - "inputs": { - "input": "{KeyframeSelection_1.outputSfMDataKeyframes}", - "featuresFolders": [ - "{FeatureExtraction_1.output}" - ], - "method": "Exhaustive" - }, - "internalInputs": { - "label": "ImageMatchingKeyframes", - "color": "#575963" - } - }, - "ImageMatching_2": { - "nodeType": "ImageMatching", - "position": [ - 1000, - 360 - ], - "inputs": { - "input": "{ApplyCalibration_1.output}", - "featuresFolders": [ - "{FeatureExtraction_1.output}" - ], - "method": "Sequential", - "nbNeighbors": 20 - }, - "internalInputs": { - "color": "#80766f" - } - }, - "ImageSegmentationBox_1": { - "nodeType": "ImageSegmentationBox", - "position": [ - 200, - 200 - ], - "inputs": { - "input": "{ImageDetectionPrompt_1.input}", - "bboxFolder": "{ImageDetectionPrompt_1.output}", - "maskInvert": true, - "keepFilename": true - }, - "internalInputs": { - "color": "#575963" - } - }, - "KeyframeSelection_1": { - "nodeType": "KeyframeSelection", - "position": [ - 200, - 0 - ], - "inputs": { - "inputPaths": [ - "{ApplyCalibration_1.output}" - ] - }, - "internalInputs": { - "color": "#575963" - } - }, - "MeshDecimate_1": { - "nodeType": "MeshDecimate", - "position": [ - 3000, - 0 - ], - "inputs": { - "input": "{MeshFiltering_1.outputMesh}", - "simplificationFactor": 0.05 - }, - "internalInputs": { - "color": "#3f3138" - } - }, - "MeshFiltering_1": { - "nodeType": "MeshFiltering", - "position": [ - 2800, - 0 - ], - "inputs": { - "inputMesh": "{Meshing_1.outputMesh}", - "filterLargeTrianglesFactor": 10.0 - }, - "internalInputs": { - "color": "#3f3138" - } - }, - "Meshing_1": { - "nodeType": "Meshing", - "position": [ - 2600, - 0 - ], - "inputs": { - "input": "{DepthMapFilter_1.input}", - "depthMapsFolder": "{DepthMapFilter_1.output}", - "estimateSpaceFromSfM": false, - "minStep": 1, - "fullWeight": 10.0, - "saveRawDensePointCloud": true - }, - "internalInputs": { - "color": "#3f3138" - } - }, - "PrepareDenseScene_1": { - "nodeType": "PrepareDenseScene", - "position": [ - 2000, - 0 - ], - "inputs": { - "input": "{SfMTriangulation_1.output}", - "maskExtension": "exr" - }, - "internalInputs": { - "color": "#3f3138" - } - }, - "Publish_1": { - "nodeType": "Publish", - "position": [ - 3600, - 100 - ], - "inputs": { - "inputFiles": [ - "{ExportAnimatedCamera_1.output}", - "{Texturing_1.output}", - "{ScenePreview_1.output}", - "{ExportDistortion_1.output}" - ] - } - }, - "ScenePreview_1": { - "nodeType": "ScenePreview", - "position": [ - 3200, - 200 - ], - "inputs": { - "cameras": "{ConvertSfMFormat_1.output}", - "model": "{MeshDecimate_1.output}", - "undistortedImages": "{ExportAnimatedCamera_1.outputUndistorted}", - "masks": "{ImageSegmentationBox_1.output}" - }, - "internalInputs": { - "color": "#4c594c" - } - }, - "SfMTransfer_1": { - "nodeType": "SfMTransfer", - "position": [ - 1600, - 0 - ], - "inputs": { - "input": "{KeyframeSelection_1.outputSfMDataKeyframes}", - "reference": "{StructureFromMotion_1.output}", - "transferLandmarks": false - }, - "internalInputs": { - "comment": "Transfer pose from final camera tracking into the keyframes-only scene.", - "color": "#3f3138" - } - }, - "SfMTriangulation_1": { - "nodeType": "SfMTriangulation", - "position": [ - 1800, - 0 - ], - "inputs": { - "input": "{SfMTransfer_1.output}", - "featuresFolders": "{StructureFromMotion_2.featuresFolders}", - "matchesFolders": "{StructureFromMotion_2.matchesFolders}", - "minAngleForTriangulation": 1.0, - "minAngleForLandmark": 0.5 - }, - "internalInputs": { - "color": "#3f3138" - } - }, - "StructureFromMotion_1": { - "nodeType": "StructureFromMotion", - "position": [ - 1400, - 200 - ], - "inputs": { - "input": "{FeatureMatching_3.input}", - "featuresFolders": "{FeatureMatching_3.featuresFolders}", - "matchesFolders": [ - "{FeatureMatching_3.output}", - "{FeatureMatching_2.output}" - ], - "describerTypes": "{FeatureMatching_3.describerTypes}", - "nbFirstUnstableCameras": 0, - "maxImagesPerGroup": 0, - "bundleAdjustmentMaxOutliers": -1, - "minInputTrackLength": 5, - "minNumberOfObservationsForTriangulation": 3, - "minAngleForTriangulation": 1.0, - "minAngleForLandmark": 0.5, - "filterTrackForks": true - }, - "internalInputs": { - "comment": "Estimate cameras parameters for the complete camera tracking sequence.", - "color": "#80766f" - } - }, - "StructureFromMotion_2": { - "nodeType": "StructureFromMotion", - "position": [ - 800, - 0 - ], - "inputs": { - "input": "{FeatureMatching_1.input}", - "featuresFolders": "{FeatureMatching_1.featuresFolders}", - "matchesFolders": [ - "{FeatureMatching_1.output}" - ], - "describerTypes": "{FeatureMatching_1.describerTypes}", - "minAngleForTriangulation": 1.0, - "minAngleForLandmark": 0.5, - "filterTrackForks": true - }, - "internalInputs": { - "comment": "Solve all keyframes first.", - "label": "StructureFromMotionKeyframes", - "color": "#575963" - } - }, - "Texturing_1": { - "nodeType": "Texturing", - "position": [ - 3200, - 0 - ], - "inputs": { - "input": "{Meshing_1.output}", - "imagesFolder": "{PrepareDenseScene_1.output}", - "inputMesh": "{MeshDecimate_1.output}" - }, - "internalInputs": { - "color": "#3f3138" - } - } - } -} \ No newline at end of file diff --git a/meshroom/pipelines/cameraTrackingWithoutCalibrationExperimental.mg b/meshroom/pipelines/cameraTrackingWithoutCalibrationExperimental.mg deleted file mode 100644 index 5b35d1f90c..0000000000 --- a/meshroom/pipelines/cameraTrackingWithoutCalibrationExperimental.mg +++ /dev/null @@ -1,567 +0,0 @@ -{ - "header": { - "releaseVersion": "2025.1.0-develop", - "fileVersion": "2.0", - "nodesVersions": { - "ApplyCalibration": "1.0", - "CameraInit": "12.0", - "ConvertDistortion": "1.0", - "ConvertSfMFormat": "2.0", - "DepthMap": "5.0", - "DepthMapFilter": "4.0", - "ExportAnimatedCamera": "2.0", - "ExportDistortion": "2.0", - "FeatureExtraction": "1.3", - "FeatureMatching": "2.0", - "ImageDetectionPrompt": "0.1", - "ImageMatching": "2.0", - "ImageMatchingMultiSfM": "1.0", - "ImageSegmentationBox": "0.1", - "KeyframeSelection": "5.0", - "MeshDecimate": "1.0", - "MeshFiltering": "3.0", - "Meshing": "7.0", - "PrepareDenseScene": "3.1", - "Publish": "1.3", - "RelativePoseEstimating": "3.0", - "ScenePreview": "2.0", - "SfMBootStraping": "3.0", - "SfMExpanding": "2.0", - "SfMTransfer": "2.1", - "SfMTriangulation": "1.0", - "Texturing": "6.0", - "TracksBuilding": "1.0" - }, - "template": true - }, - "graph": { - "ApplyCalibration_1": { - "nodeType": "ApplyCalibration", - "position": [ - 0, - 0 - ], - "inputs": { - "input": "{CameraInit_1.output}" - }, - "internalInputs": { - "color": "#575963" - } - }, - "CameraInit_1": { - "nodeType": "CameraInit", - "position": [ - -200, - 0 - ], - "inputs": {}, - "internalInputs": { - "color": "#575963" - } - }, - "ConvertDistortion_1": { - "nodeType": "ConvertDistortion", - "position": [ - 2400, - 360 - ], - "inputs": { - "input": "{SfMExpanding_2.output}" - }, - "internalInputs": { - "color": "#80766f" - } - }, - "ConvertSfMFormat_1": { - "nodeType": "ConvertSfMFormat", - "position": [ - 3800, - 200 - ], - "inputs": { - "input": "{ExportAnimatedCamera_1.input}", - "fileExt": "json", - "describerTypes": "{TracksBuilding_2.describerTypes}", - "structure": false, - "observations": false - }, - "internalInputs": { - "color": "#4c594c" - } - }, - "DepthMapFilter_1": { - "nodeType": "DepthMapFilter", - "position": [ - 3200, - 0 - ], - "inputs": { - "input": "{DepthMap_1.input}", - "depthMapsFolder": "{DepthMap_1.output}" - }, - "internalInputs": { - "color": "#3f3138" - } - }, - "DepthMap_1": { - "nodeType": "DepthMap", - "position": [ - 3000, - 0 - ], - "inputs": { - "input": "{PrepareDenseScene_1.input}", - "imagesFolder": "{PrepareDenseScene_1.output}", - "downscale": 1 - }, - "internalInputs": { - "color": "#3f3138" - } - }, - "ExportAnimatedCamera_1": { - "nodeType": "ExportAnimatedCamera", - "position": [ - 2600, - 200 - ], - "inputs": { - "input": "{SfMExpanding_2.output}", - "exportUndistortedImages": true - }, - "internalInputs": { - "color": "#80766f" - } - }, - "ExportDistortion_1": { - "nodeType": "ExportDistortion", - "position": [ - 2600, - 360 - ], - "inputs": { - "input": "{ConvertDistortion_1.output}", - "exportLensGridsUndistorted": false - }, - "internalInputs": { - "color": "#80766f" - } - }, - "FeatureExtraction_1": { - "nodeType": "FeatureExtraction", - "position": [ - 400, - 200 - ], - "inputs": { - "input": "{ApplyCalibration_1.output}", - "masksFolder": "{ImageSegmentationBox_1.output}", - "maskExtension": "exr" - }, - "internalInputs": { - "color": "#575963" - } - }, - "FeatureMatching_1": { - "nodeType": "FeatureMatching", - "position": [ - 600, - 0 - ], - "inputs": { - "input": "{ImageMatching_1.input}", - "featuresFolders": "{ImageMatching_1.featuresFolders}", - "imagePairsList": "{ImageMatching_1.output}", - "describerTypes": "{FeatureExtraction_1.describerTypes}" - }, - "internalInputs": { - "label": "FeatureMatchingKeyframes", - "color": "#575963" - } - }, - "FeatureMatching_2": { - "nodeType": "FeatureMatching", - "position": [ - 1800, - 360 - ], - "inputs": { - "input": "{ImageMatching_2.input}", - "featuresFolders": "{ImageMatching_2.featuresFolders}", - "imagePairsList": "{ImageMatching_2.output}" - }, - "internalInputs": { - "label": "FeatureMatchingAllFrames", - "color": "#80766f" - } - }, - "FeatureMatching_3": { - "nodeType": "FeatureMatching", - "position": [ - 1800, - 200 - ], - "inputs": { - "input": "{ImageMatchingMultiSfM_1.outputCombinedSfM}", - "featuresFolders": "{ImageMatchingMultiSfM_1.featuresFolders}", - "imagePairsList": "{ImageMatchingMultiSfM_1.output}", - "describerTypes": "{FeatureExtraction_1.describerTypes}" - }, - "internalInputs": { - "label": "FeatureMatchingFramesToKeyframes", - "color": "#80766f" - } - }, - "ImageDetectionPrompt_1": { - "nodeType": "ImageDetectionPrompt", - "position": [ - 0, - 200 - ], - "inputs": { - "input": "{CameraInit_1.output}" - }, - "internalInputs": { - "color": "#575963" - } - }, - "ImageMatchingMultiSfM_1": { - "nodeType": "ImageMatchingMultiSfM", - "position": [ - 1600, - 200 - ], - "inputs": { - "input": "{KeyframeSelection_1.outputSfMDataFrames}", - "inputB": "{SfMExpanding_1.output}", - "featuresFolders": [ - "{FeatureExtraction_1.output}" - ], - "method": "VocabularyTree", - "matchingMode": "a/b", - "nbMatches": 20 - }, - "internalInputs": { - "color": "#80766f" - } - }, - "ImageMatching_1": { - "nodeType": "ImageMatching", - "position": [ - 400, - 0 - ], - "inputs": { - "input": "{KeyframeSelection_1.outputSfMDataKeyframes}", - "featuresFolders": [ - "{FeatureExtraction_1.output}" - ], - "method": "Exhaustive" - }, - "internalInputs": { - "label": "ImageMatchingKeyframes", - "color": "#575963" - } - }, - "ImageMatching_2": { - "nodeType": "ImageMatching", - "position": [ - 1600, - 360 - ], - "inputs": { - "input": "{ApplyCalibration_1.output}", - "featuresFolders": [ - "{FeatureExtraction_1.output}" - ], - "method": "Sequential", - "nbNeighbors": 20 - }, - "internalInputs": { - "color": "#80766f" - } - }, - "ImageSegmentationBox_1": { - "nodeType": "ImageSegmentationBox", - "position": [ - 200, - 200 - ], - "inputs": { - "input": "{ImageDetectionPrompt_1.input}", - "bboxFolder": "{ImageDetectionPrompt_1.output}", - "maskInvert": true, - "keepFilename": true - }, - "internalInputs": { - "color": "#575963" - } - }, - "KeyframeSelection_1": { - "nodeType": "KeyframeSelection", - "position": [ - 200, - 0 - ], - "inputs": { - "inputPaths": [ - "{ApplyCalibration_1.output}" - ] - }, - "internalInputs": { - "color": "#575963" - } - }, - "MeshDecimate_1": { - "nodeType": "MeshDecimate", - "position": [ - 3800, - 0 - ], - "inputs": { - "input": "{MeshFiltering_1.outputMesh}", - "simplificationFactor": 0.05 - }, - "internalInputs": { - "color": "#3f3138" - } - }, - "MeshFiltering_1": { - "nodeType": "MeshFiltering", - "position": [ - 3600, - 0 - ], - "inputs": { - "inputMesh": "{Meshing_1.outputMesh}", - "filterLargeTrianglesFactor": 10.0 - }, - "internalInputs": { - "color": "#3f3138" - } - }, - "Meshing_1": { - "nodeType": "Meshing", - "position": [ - 3400, - 0 - ], - "inputs": { - "input": "{DepthMapFilter_1.input}", - "depthMapsFolder": "{DepthMapFilter_1.output}", - "estimateSpaceFromSfM": false, - "minStep": 1, - "fullWeight": 10.0, - "saveRawDensePointCloud": true - }, - "internalInputs": { - "color": "#3f3138" - } - }, - "PrepareDenseScene_1": { - "nodeType": "PrepareDenseScene", - "position": [ - 2800, - 0 - ], - "inputs": { - "input": "{SfMTriangulation_1.output}", - "maskExtension": "exr" - }, - "internalInputs": { - "color": "#3f3138" - } - }, - "Publish_1": { - "nodeType": "Publish", - "position": [ - 4400, - 100 - ], - "inputs": { - "inputFiles": [ - "{ExportAnimatedCamera_1.output}", - "{Texturing_1.output}", - "{ScenePreview_1.output}", - "{ExportDistortion_1.output}" - ] - } - }, - "RelativePoseEstimating_1": { - "nodeType": "RelativePoseEstimating", - "position": [ - 1000, - 0 - ], - "inputs": { - "input": "{TracksBuilding_1.input}", - "tracksFilename": "{TracksBuilding_1.output}", - "countIterations": 50000, - "minInliers": 100 - }, - "internalInputs": { - "color": "#575963" - } - }, - "ScenePreview_1": { - "nodeType": "ScenePreview", - "position": [ - 4000, - 200 - ], - "inputs": { - "cameras": "{ConvertSfMFormat_1.output}", - "model": "{MeshDecimate_1.output}", - "undistortedImages": "{ExportAnimatedCamera_1.outputUndistorted}", - "masks": "{ImageSegmentationBox_1.output}" - }, - "internalInputs": { - "color": "#4c594c" - } - }, - "SfMBootStraping_1": { - "nodeType": "SfMBootStraping", - "position": [ - 1200, - 0 - ], - "inputs": { - "input": "{RelativePoseEstimating_1.input}", - "tracksFilename": "{RelativePoseEstimating_1.tracksFilename}", - "pairs": "{RelativePoseEstimating_1.output}" - }, - "internalInputs": { - "color": "#575963" - } - }, - "SfMExpanding_1": { - "nodeType": "SfMExpanding", - "position": [ - 1400, - 0 - ], - "inputs": { - "input": "{SfMBootStraping_1.output}", - "tracksFilename": "{SfMBootStraping_1.tracksFilename}", - "meshFilename": "{SfMBootStraping_1.meshFilename}", - "minAngleForTriangulation": 1.0, - "minAngleForLandmark": 0.5 - }, - "internalInputs": { - "comment": "Estimate cameras parameters for the keyframes.", - "label": "SfMExpandingKeys", - "color": "#575963" - } - }, - "SfMExpanding_2": { - "nodeType": "SfMExpanding", - "position": [ - 2200, - 200 - ], - "inputs": { - "input": "{TracksBuilding_2.input}", - "tracksFilename": "{TracksBuilding_2.output}", - "meshFilename": "{SfMExpanding_1.meshFilename}", - "nbFirstUnstableCameras": 0, - "maxImagesPerGroup": 0, - "bundleAdjustmentMaxOutliers": 5000000, - "minNumberOfObservationsForTriangulation": 3, - "minAngleForTriangulation": 1.0, - "minAngleForLandmark": 0.5 - }, - "internalInputs": { - "comment": "Estimate cameras parameters for the complete camera tracking sequence.", - "label": "SfMExpandingAll", - "color": "#80766f" - } - }, - "SfMTransfer_1": { - "nodeType": "SfMTransfer", - "position": [ - 2400, - 0 - ], - "inputs": { - "input": "{KeyframeSelection_1.outputSfMDataKeyframes}", - "reference": "{SfMExpanding_2.output}", - "transferLandmarks": false - }, - "internalInputs": { - "comment": "Transfer pose from final camera tracking into the keyframes-only scene.", - "color": "#3f3138" - } - }, - "SfMTriangulation_1": { - "nodeType": "SfMTriangulation", - "position": [ - 2600, - 0 - ], - "inputs": { - "input": "{SfMTransfer_1.output}", - "featuresFolders": "{TracksBuilding_1.featuresFolders}", - "matchesFolders": "{TracksBuilding_1.matchesFolders}", - "minAngleForTriangulation": 1.0, - "minAngleForLandmark": 0.5 - }, - "internalInputs": { - "color": "#3f3138" - } - }, - "Texturing_1": { - "nodeType": "Texturing", - "position": [ - 4000, - 0 - ], - "inputs": { - "input": "{Meshing_1.output}", - "imagesFolder": "{PrepareDenseScene_1.output}", - "inputMesh": "{MeshDecimate_1.output}" - }, - "internalInputs": { - "color": "#3f3138" - } - }, - "TracksBuilding_1": { - "nodeType": "TracksBuilding", - "position": [ - 800, - 0 - ], - "inputs": { - "input": "{FeatureMatching_1.input}", - "featuresFolders": "{FeatureMatching_1.featuresFolders}", - "matchesFolders": [ - "{FeatureMatching_1.output}" - ], - "describerTypes": "{FeatureMatching_1.describerTypes}", - "filterTrackForks": true - }, - "internalInputs": { - "color": "#575963" - } - }, - "TracksBuilding_2": { - "nodeType": "TracksBuilding", - "position": [ - 2000, - 200 - ], - "inputs": { - "input": "{FeatureMatching_3.input}", - "featuresFolders": "{FeatureMatching_3.featuresFolders}", - "matchesFolders": [ - "{FeatureMatching_2.output}", - "{FeatureMatching_3.output}" - ], - "describerTypes": "{FeatureMatching_3.describerTypes}", - "minInputTrackLength": 5, - "filterTrackForks": true - }, - "internalInputs": { - "color": "#80766f" - } - } - } -} \ No newline at end of file diff --git a/meshroom/pipelines/distortionCalibration.mg b/meshroom/pipelines/distortionCalibration.mg deleted file mode 100644 index 226e911e5b..0000000000 --- a/meshroom/pipelines/distortionCalibration.mg +++ /dev/null @@ -1,69 +0,0 @@ -{ - "header": { - "releaseVersion": "2025.1.0-develop", - "fileVersion": "2.0", - "template": true, - "nodesVersions": { - "CameraInit": "12.0", - "CheckerboardDetection": "1.0", - "DistortionCalibration": "5.0", - "ExportDistortion": "2.0", - "Publish": "1.3" - } - }, - "graph": { - "CameraInit_1": { - "nodeType": "CameraInit", - "position": [ - 0, - 0 - ], - "inputs": {} - }, - "CheckerboardDetection_1": { - "nodeType": "CheckerboardDetection", - "position": [ - 200, - 0 - ], - "inputs": { - "input": "{CameraInit_1.output}", - "useNestedGrids": true, - "exportDebugImages": true - } - }, - "DistortionCalibration_1": { - "nodeType": "DistortionCalibration", - "position": [ - 400, - 0 - ], - "inputs": { - "input": "{CheckerboardDetection_1.input}", - "checkerboards": "{CheckerboardDetection_1.output}" - } - }, - "ExportDistortion_1": { - "nodeType": "ExportDistortion", - "position": [ - 600, - 0 - ], - "inputs": { - "input": "{DistortionCalibration_1.output}" - } - }, - "Publish_1": { - "nodeType": "Publish", - "position": [ - 800, - 0 - ], - "inputs": { - "inputFiles": [ - "{ExportDistortion_1.output}" - ] - } - } - } -} \ No newline at end of file diff --git a/meshroom/pipelines/hdrFusion.mg b/meshroom/pipelines/hdrFusion.mg deleted file mode 100644 index b3d70333d8..0000000000 --- a/meshroom/pipelines/hdrFusion.mg +++ /dev/null @@ -1,77 +0,0 @@ -{ - "header": { - "nodesVersions": { - "CameraInit": "12.0", - "LdrToHdrCalibration": "3.1", - "LdrToHdrMerge": "4.1", - "LdrToHdrSampling": "4.0", - "Publish": "1.3" - }, - "releaseVersion": "2025.1.0-develop", - "fileVersion": "2.0", - "template": true - }, - "graph": { - "CameraInit_1": { - "nodeType": "CameraInit", - "position": [ - 0, - 0 - ], - "inputs": {} - }, - "LdrToHdrCalibration_1": { - "nodeType": "LdrToHdrCalibration", - "position": [ - 400, - 0 - ], - "inputs": { - "input": "{LdrToHdrSampling_1.input}", - "samples": "{LdrToHdrSampling_1.output}", - "userNbBrackets": "{LdrToHdrSampling_1.userNbBrackets}", - "byPass": "{LdrToHdrSampling_1.byPass}", - "calibrationMethod": "{LdrToHdrSampling_1.calibrationMethod}", - "channelQuantizationPower": "{LdrToHdrSampling_1.channelQuantizationPower}", - "workingColorSpace": "{LdrToHdrSampling_1.workingColorSpace}" - } - }, - "LdrToHdrMerge_1": { - "nodeType": "LdrToHdrMerge", - "position": [ - 600, - 0 - ], - "inputs": { - "input": "{LdrToHdrCalibration_1.input}", - "response": "{LdrToHdrCalibration_1.response}", - "userNbBrackets": "{LdrToHdrCalibration_1.userNbBrackets}", - "byPass": "{LdrToHdrCalibration_1.byPass}", - "channelQuantizationPower": "{LdrToHdrCalibration_1.channelQuantizationPower}", - "workingColorSpace": "{LdrToHdrCalibration_1.workingColorSpace}" - } - }, - "LdrToHdrSampling_1": { - "nodeType": "LdrToHdrSampling", - "position": [ - 200, - 0 - ], - "inputs": { - "input": "{CameraInit_1.output}" - } - }, - "Publish_1": { - "nodeType": "Publish", - "position": [ - 800, - 0 - ], - "inputs": { - "inputFiles": [ - "{LdrToHdrMerge_1.outputFolder}" - ] - } - } - } -} \ No newline at end of file diff --git a/meshroom/pipelines/multi-viewPhotometricStereo.mg b/meshroom/pipelines/multi-viewPhotometricStereo.mg deleted file mode 100644 index c19d53f354..0000000000 --- a/meshroom/pipelines/multi-viewPhotometricStereo.mg +++ /dev/null @@ -1,277 +0,0 @@ -{ - "header": { - "pipelineVersion": "2.2", - "releaseVersion": "2025.1.0-develop", - "fileVersion": "2.0", - "template": true, - "nodesVersions": { - "CameraInit": "12.0", - "DepthMap": "5.0", - "DepthMapFilter": "4.0", - "FeatureExtraction": "1.3", - "FeatureMatching": "2.0", - "ImageMatching": "2.0", - "LightingCalibration": "1.0", - "MeshFiltering": "3.0", - "Meshing": "7.0", - "PhotometricStereo": "1.0", - "PrepareDenseScene": "3.1", - "SfMFilter": "1.0", - "SfMTransfer": "2.1", - "SphereDetection": "1.0", - "StructureFromMotion": "3.3", - "Texturing": "6.0" - } - }, - "graph": { - "CameraInit_1": { - "nodeType": "CameraInit", - "position": [ - -400, - 200 - ], - "inputs": { - "rawColorInterpretation": "LibRawWhiteBalancing" - } - }, - "DepthMapFilter_1": { - "nodeType": "DepthMapFilter", - "position": [ - 1200, - 0 - ], - "inputs": { - "input": "{DepthMap_1.input}", - "depthMapsFolder": "{DepthMap_1.output}" - } - }, - "DepthMap_1": { - "nodeType": "DepthMap", - "position": [ - 1000, - 0 - ], - "inputs": { - "input": "{PrepareDenseScene_1.input}", - "imagesFolder": "{PrepareDenseScene_1.output}" - } - }, - "FeatureExtraction_1": { - "nodeType": "FeatureExtraction", - "position": [ - 0, - 0 - ], - "inputs": { - "input": "{SfMFilter_1.outputSfMData_selected}" - } - }, - "FeatureMatching_1": { - "nodeType": "FeatureMatching", - "position": [ - 400, - 0 - ], - "inputs": { - "input": "{ImageMatching_1.input}", - "featuresFolders": "{ImageMatching_1.featuresFolders}", - "imagePairsList": "{ImageMatching_1.output}", - "describerTypes": "{FeatureExtraction_1.describerTypes}", - "maxIteration": 2048 - } - }, - "ImageMatching_1": { - "nodeType": "ImageMatching", - "position": [ - 200, - 0 - ], - "inputs": { - "input": "{FeatureExtraction_1.input}", - "featuresFolders": [ - "{FeatureExtraction_1.output}" - ] - } - }, - "LightingCalibration_1": { - "nodeType": "LightingCalibration", - "position": [ - 1200, - 200 - ], - "inputs": { - "inputPath": "{SphereDetection_1.input}", - "inputDetection": "{SphereDetection_1.output}" - } - }, - "MeshFiltering_1": { - "nodeType": "MeshFiltering", - "position": [ - 1600, - 0 - ], - "inputs": { - "inputMesh": "{Meshing_1.outputMesh}" - } - }, - "Meshing_1": { - "nodeType": "Meshing", - "position": [ - 1400, - 0 - ], - "inputs": { - "input": "{DepthMapFilter_1.input}", - "depthMapsFolder": "{DepthMapFilter_1.output}" - } - }, - "PhotometricStereo_1": { - "nodeType": "PhotometricStereo", - "position": [ - 1400, - 200 - ], - "inputs": { - "inputPath": "{LightingCalibration_1.inputPath}", - "pathToJSONLightFile": "{LightingCalibration_1.outputFile}" - } - }, - "PrepareDenseScene_1": { - "nodeType": "PrepareDenseScene", - "position": [ - 800, - 0 - ], - "inputs": { - "input": "{StructureFromMotion_1.output}" - } - }, - "PrepareDenseScene_2": { - "nodeType": "PrepareDenseScene", - "position": [ - 2200, - 200 - ], - "inputs": { - "input": "{PhotometricStereo_1.outputSfmDataAlbedo}" - } - }, - "PrepareDenseScene_3": { - "nodeType": "PrepareDenseScene", - "position": [ - 2200, - 400 - ], - "inputs": { - "input": "{PhotometricStereo_1.outputSfmDataNormal}" - } - }, - "PrepareDenseScene_4": { - "nodeType": "PrepareDenseScene", - "position": [ - 2200, - 600 - ], - "inputs": { - "input": "{PhotometricStereo_1.outputSfmDataNormalPNG}" - } - }, - "SfMFilter_1": { - "nodeType": "SfMFilter", - "position": [ - -200, - 200 - ], - "inputs": { - "inputFile": "{CameraInit_1.output}", - "fileMatchingPattern": ".*/.*ambiant.*" - } - }, - "SfMTransfer_1": { - "nodeType": "SfMTransfer", - "position": [ - 800, - 200 - ], - "inputs": { - "input": "{SfMFilter_1.outputSfMData_unselected}", - "reference": "{StructureFromMotion_1.output}", - "method": "from_poseid" - } - }, - "SphereDetection_1": { - "nodeType": "SphereDetection", - "position": [ - 1000, - 200 - ], - "inputs": { - "input": "{SfMTransfer_1.output}" - } - }, - "StructureFromMotion_1": { - "nodeType": "StructureFromMotion", - "position": [ - 600, - 0 - ], - "inputs": { - "input": "{FeatureMatching_1.input}", - "featuresFolders": "{FeatureMatching_1.featuresFolders}", - "matchesFolders": [ - "{FeatureMatching_1.output}" - ], - "describerTypes": "{FeatureMatching_1.describerTypes}", - "localizerEstimatorMaxIterations": 4096 - } - }, - "Texturing_1": { - "nodeType": "Texturing", - "position": [ - 1800, - 0 - ], - "inputs": { - "input": "{Meshing_1.output}", - "imagesFolder": "{DepthMap_1.imagesFolder}", - "inputMesh": "{MeshFiltering_1.outputMesh}" - } - }, - "Texturing_2": { - "nodeType": "Texturing", - "position": [ - 2400, - 200 - ], - "inputs": { - "input": "{Meshing_1.output}", - "imagesFolder": "{PrepareDenseScene_2.output}", - "inputMesh": "{MeshFiltering_1.outputMesh}" - } - }, - "Texturing_3": { - "nodeType": "Texturing", - "position": [ - 2400, - 400 - ], - "inputs": { - "input": "{Meshing_1.output}", - "imagesFolder": "{PrepareDenseScene_3.output}", - "inputMesh": "{MeshFiltering_1.outputMesh}" - } - }, - "Texturing_4": { - "nodeType": "Texturing", - "position": [ - 2400, - 600 - ], - "inputs": { - "input": "{Meshing_1.output}", - "imagesFolder": "{PrepareDenseScene_4.output}", - "inputMesh": "{MeshFiltering_1.outputMesh}" - } - } - } -} \ No newline at end of file diff --git a/meshroom/pipelines/nodalCameraTracking.mg b/meshroom/pipelines/nodalCameraTracking.mg deleted file mode 100644 index 55bd70122d..0000000000 --- a/meshroom/pipelines/nodalCameraTracking.mg +++ /dev/null @@ -1,293 +0,0 @@ -{ - "header": { - "releaseVersion": "2025.1.0-develop", - "fileVersion": "2.0", - "template": true, - "nodesVersions": { - "ApplyCalibration": "1.0", - "CameraInit": "12.0", - "CheckerboardDetection": "1.0", - "ConvertSfMFormat": "2.0", - "DistortionCalibration": "5.0", - "ExportAnimatedCamera": "2.0", - "ExportDistortion": "2.0", - "FeatureExtraction": "1.3", - "FeatureMatching": "2.0", - "ImageDetectionPrompt": "0.1", - "ImageMatching": "2.0", - "ImageSegmentationBox": "0.1", - "NodalSfM": "2.0", - "Publish": "1.3", - "RelativePoseEstimating": "3.0", - "ScenePreview": "2.0", - "TracksBuilding": "1.0" - } - }, - "graph": { - "ApplyCalibration_1": { - "nodeType": "ApplyCalibration", - "position": [ - 0, - 0 - ], - "inputs": { - "input": "{CameraInit_1.output}", - "calibration": "{DistortionCalibration_1.output}" - }, - "internalInputs": { - "color": "#80766f" - } - }, - "CameraInit_1": { - "nodeType": "CameraInit", - "position": [ - -200, - 0 - ], - "inputs": {}, - "internalInputs": { - "color": "#80766f" - } - }, - "CameraInit_2": { - "nodeType": "CameraInit", - "position": [ - -600, - -160 - ], - "inputs": {}, - "internalInputs": { - "label": "CameraInitLensGrid", - "color": "#302e2e" - } - }, - "CheckerboardDetection_1": { - "nodeType": "CheckerboardDetection", - "position": [ - -400, - -160 - ], - "inputs": { - "input": "{CameraInit_2.output}", - "useNestedGrids": true, - "exportDebugImages": true - }, - "internalInputs": { - "color": "#302e2e" - } - }, - "ConvertSfMFormat_1": { - "nodeType": "ConvertSfMFormat", - "position": [ - 1600, - 200 - ], - "inputs": { - "input": "{NodalSfM_1.output}", - "fileExt": "sfm", - "structure": false, - "observations": false - }, - "internalInputs": { - "color": "#4c594c" - } - }, - "DistortionCalibration_1": { - "nodeType": "DistortionCalibration", - "position": [ - -200, - -160 - ], - "inputs": { - "input": "{CheckerboardDetection_1.input}", - "checkerboards": "{CheckerboardDetection_1.output}" - }, - "internalInputs": { - "color": "#302e2e" - } - }, - "ExportAnimatedCamera_1": { - "nodeType": "ExportAnimatedCamera", - "position": [ - 1600, - 0 - ], - "inputs": { - "input": "{NodalSfM_1.output}", - "exportUndistortedImages": true - }, - "internalInputs": { - "color": "#80766f" - } - }, - "ExportDistortion_1": { - "nodeType": "ExportDistortion", - "position": [ - 0, - -160 - ], - "inputs": { - "input": "{DistortionCalibration_1.output}" - }, - "internalInputs": { - "color": "#302e2e" - } - }, - "FeatureExtraction_1": { - "nodeType": "FeatureExtraction", - "position": [ - 400, - 0 - ], - "inputs": { - "input": "{ApplyCalibration_1.output}", - "masksFolder": "{ImageSegmentationBox_1.output}" - }, - "internalInputs": { - "color": "#80766f" - } - }, - "FeatureMatching_1": { - "nodeType": "FeatureMatching", - "position": [ - 800, - 0 - ], - "inputs": { - "input": "{ImageMatching_1.input}", - "featuresFolders": "{ImageMatching_1.featuresFolders}", - "imagePairsList": "{ImageMatching_1.output}", - "describerTypes": "{FeatureExtraction_1.describerTypes}" - }, - "internalInputs": { - "color": "#80766f" - } - }, - "ImageDetectionPrompt_1": { - "nodeType": "ImageDetectionPrompt", - "position": [ - 0, - 200 - ], - "inputs": { - "input": "{CameraInit_1.output}" - }, - "internalInputs": { - "color": "#80766f" - } - }, - "ImageMatching_1": { - "nodeType": "ImageMatching", - "position": [ - 600, - 0 - ], - "inputs": { - "input": "{FeatureExtraction_1.input}", - "featuresFolders": [ - "{FeatureExtraction_1.output}" - ] - }, - "internalInputs": { - "color": "#80766f" - } - }, - "ImageSegmentationBox_1": { - "nodeType": "ImageSegmentationBox", - "position": [ - 200, - 200 - ], - "inputs": { - "input": "{ImageDetectionPrompt_1.input}", - "bboxFolder": "{ImageDetectionPrompt_1.output}", - "maskInvert": true, - "keepFilename": true - }, - "internalInputs": { - "color": "#80766f" - } - }, - "NodalSfM_1": { - "nodeType": "NodalSfM", - "position": [ - 1400, - 0 - ], - "inputs": { - "input": "{RelativePoseEstimating_1.input}", - "tracksFilename": "{RelativePoseEstimating_1.tracksFilename}", - "pairs": "{RelativePoseEstimating_1.output}" - }, - "internalInputs": { - "color": "#80766f" - } - }, - "Publish_1": { - "nodeType": "Publish", - "position": [ - 2000, - 0 - ], - "inputs": { - "inputFiles": [ - "{ExportAnimatedCamera_1.output}", - "{ScenePreview_1.output}", - "{ExportDistortion_1.output}" - ] - } - }, - "RelativePoseEstimating_1": { - "nodeType": "RelativePoseEstimating", - "position": [ - 1200, - 0 - ], - "inputs": { - "input": "{TracksBuilding_1.input}", - "tracksFilename": "{TracksBuilding_1.output}", - "enforcePureRotation": true - }, - "internalInputs": { - "color": "#80766f" - } - }, - "ScenePreview_1": { - "nodeType": "ScenePreview", - "position": [ - 1800, - 200 - ], - "inputs": { - "cameras": "{ConvertSfMFormat_1.output}", - "model": "{NodalSfM_1.output}", - "undistortedImages": "{ExportAnimatedCamera_1.outputUndistorted}", - "masks": "{ImageSegmentationBox_1.output}", - "pointCloudParams": { - "particleSize": 0.001, - "particleColor": "Red" - } - }, - "internalInputs": { - "color": "#4c594c" - } - }, - "TracksBuilding_1": { - "nodeType": "TracksBuilding", - "position": [ - 1000, - 0 - ], - "inputs": { - "input": "{FeatureMatching_1.input}", - "featuresFolders": "{FeatureMatching_1.featuresFolders}", - "matchesFolders": [ - "{FeatureMatching_1.output}" - ] - }, - "internalInputs": { - "color": "#80766f" - } - } - } -} \ No newline at end of file diff --git a/meshroom/pipelines/nodalCameraTrackingWithoutCalibration.mg b/meshroom/pipelines/nodalCameraTrackingWithoutCalibration.mg deleted file mode 100644 index 6de92754cc..0000000000 --- a/meshroom/pipelines/nodalCameraTrackingWithoutCalibration.mg +++ /dev/null @@ -1,250 +0,0 @@ -{ - "header": { - "releaseVersion": "2025.1.0-develop", - "fileVersion": "2.0", - "template": true, - "nodesVersions": { - "CameraInit": "12.0", - "ConvertDistortion": "1.0", - "ConvertSfMFormat": "2.0", - "ExportAnimatedCamera": "2.0", - "ExportDistortion": "2.0", - "FeatureExtraction": "1.3", - "FeatureMatching": "2.0", - "ImageDetectionPrompt": "0.1", - "ImageMatching": "2.0", - "ImageSegmentationBox": "0.1", - "NodalSfM": "2.0", - "Publish": "1.3", - "RelativePoseEstimating": "3.0", - "ScenePreview": "2.0", - "TracksBuilding": "1.0" - } - }, - "graph": { - "CameraInit_1": { - "nodeType": "CameraInit", - "position": [ - -400, - 0 - ], - "inputs": {}, - "internalInputs": { - "color": "#80766f" - } - }, - "ConvertDistortion_1": { - "nodeType": "ConvertDistortion", - "position": [ - 1600, - 0 - ], - "inputs": { - "input": "{ExportAnimatedCamera_1.input}" - }, - "internalInputs": { - "color": "#80766f" - } - }, - "ConvertSfMFormat_1": { - "nodeType": "ConvertSfMFormat", - "position": [ - 1400, - 200 - ], - "inputs": { - "input": "{NodalSfM_1.output}", - "fileExt": "sfm", - "structure": false, - "observations": false - }, - "internalInputs": { - "color": "#4c594c" - } - }, - "ExportAnimatedCamera_1": { - "nodeType": "ExportAnimatedCamera", - "position": [ - 1400, - 0 - ], - "inputs": { - "input": "{NodalSfM_1.output}", - "exportUndistortedImages": true - }, - "internalInputs": { - "color": "#80766f" - } - }, - "ExportDistortion_1": { - "nodeType": "ExportDistortion", - "position": [ - 1800, - 0 - ], - "inputs": { - "input": "{ConvertDistortion_1.output}", - "exportLensGridsUndistorted": false - }, - "internalInputs": { - "color": "#80766f" - } - }, - "FeatureExtraction_1": { - "nodeType": "FeatureExtraction", - "position": [ - 200, - 0 - ], - "inputs": { - "input": "{ImageSegmentationBox_1.input}", - "masksFolder": "{ImageSegmentationBox_1.output}" - }, - "internalInputs": { - "color": "#80766f" - } - }, - "FeatureMatching_1": { - "nodeType": "FeatureMatching", - "position": [ - 600, - 0 - ], - "inputs": { - "input": "{ImageMatching_1.input}", - "featuresFolders": "{ImageMatching_1.featuresFolders}", - "imagePairsList": "{ImageMatching_1.output}", - "describerTypes": "{FeatureExtraction_1.describerTypes}" - }, - "internalInputs": { - "color": "#80766f" - } - }, - "ImageDetectionPrompt_1": { - "nodeType": "ImageDetectionPrompt", - "position": [ - -200, - 0 - ], - "inputs": { - "input": "{CameraInit_1.output}" - }, - "internalInputs": { - "color": "#80766f" - } - }, - "ImageMatching_1": { - "nodeType": "ImageMatching", - "position": [ - 400, - 0 - ], - "inputs": { - "input": "{FeatureExtraction_1.input}", - "featuresFolders": [ - "{FeatureExtraction_1.output}" - ] - }, - "internalInputs": { - "color": "#80766f" - } - }, - "ImageSegmentationBox_1": { - "nodeType": "ImageSegmentationBox", - "position": [ - 0, - 0 - ], - "inputs": { - "input": "{ImageDetectionPrompt_1.input}", - "bboxFolder": "{ImageDetectionPrompt_1.output}", - "maskInvert": true, - "keepFilename": true - }, - "internalInputs": { - "color": "#80766f" - } - }, - "NodalSfM_1": { - "nodeType": "NodalSfM", - "position": [ - 1200, - 0 - ], - "inputs": { - "input": "{RelativePoseEstimating_1.input}", - "tracksFilename": "{RelativePoseEstimating_1.tracksFilename}", - "pairs": "{RelativePoseEstimating_1.output}" - }, - "internalInputs": { - "color": "#80766f" - } - }, - "Publish_1": { - "nodeType": "Publish", - "position": [ - 2100, - 100 - ], - "inputs": { - "inputFiles": [ - "{ExportAnimatedCamera_1.output}", - "{ScenePreview_1.output}", - "{ExportDistortion_1.output}" - ] - } - }, - "RelativePoseEstimating_1": { - "nodeType": "RelativePoseEstimating", - "position": [ - 1000, - 0 - ], - "inputs": { - "input": "{TracksBuilding_1.input}", - "tracksFilename": "{TracksBuilding_1.output}", - "enforcePureRotation": true - }, - "internalInputs": { - "color": "#80766f" - } - }, - "ScenePreview_1": { - "nodeType": "ScenePreview", - "position": [ - 1600, - 200 - ], - "inputs": { - "cameras": "{ConvertSfMFormat_1.output}", - "model": "{NodalSfM_1.output}", - "undistortedImages": "{ExportAnimatedCamera_1.outputUndistorted}", - "masks": "{ImageSegmentationBox_1.output}", - "pointCloudParams": { - "particleSize": 0.001, - "particleColor": "Red" - } - }, - "internalInputs": { - "color": "#4c594c" - } - }, - "TracksBuilding_1": { - "nodeType": "TracksBuilding", - "position": [ - 800, - 0 - ], - "inputs": { - "input": "{FeatureMatching_1.input}", - "featuresFolders": "{FeatureMatching_1.featuresFolders}", - "matchesFolders": [ - "{FeatureMatching_1.output}" - ] - }, - "internalInputs": { - "color": "#80766f" - } - } - } -} \ No newline at end of file diff --git a/meshroom/pipelines/panoramaFisheyeHdr.mg b/meshroom/pipelines/panoramaFisheyeHdr.mg deleted file mode 100644 index 03daf308d2..0000000000 --- a/meshroom/pipelines/panoramaFisheyeHdr.mg +++ /dev/null @@ -1,238 +0,0 @@ -{ - "header": { - "nodesVersions": { - "CameraInit": "12.0", - "FeatureExtraction": "1.3", - "FeatureMatching": "2.0", - "ImageMatching": "2.0", - "LdrToHdrCalibration": "3.1", - "LdrToHdrMerge": "4.1", - "LdrToHdrSampling": "4.0", - "PanoramaCompositing": "2.0", - "PanoramaEstimation": "1.0", - "PanoramaInit": "2.0", - "PanoramaMerging": "1.0", - "PanoramaPostProcessing": "2.0", - "PanoramaPrepareImages": "1.1", - "PanoramaSeams": "2.0", - "PanoramaWarping": "1.1", - "Publish": "1.3", - "SfMTransform": "3.1" - }, - "releaseVersion": "2025.1.0-develop", - "fileVersion": "2.0", - "template": true - }, - "graph": { - "CameraInit_1": { - "nodeType": "CameraInit", - "position": [ - 0, - 0 - ], - "inputs": {} - }, - "FeatureExtraction_1": { - "nodeType": "FeatureExtraction", - "position": [ - 1200, - 0 - ], - "inputs": { - "input": "{PanoramaInit_1.outSfMData}", - "describerTypes": [ - "sift" - ], - "describerPreset": "high", - "describerQuality": "high" - } - }, - "FeatureMatching_1": { - "nodeType": "FeatureMatching", - "position": [ - 1600, - 0 - ], - "inputs": { - "input": "{ImageMatching_1.input}", - "featuresFolders": "{ImageMatching_1.featuresFolders}", - "imagePairsList": "{ImageMatching_1.output}", - "describerTypes": "{FeatureExtraction_1.describerTypes}", - "minRequired2DMotion": 5.0 - } - }, - "ImageMatching_1": { - "nodeType": "ImageMatching", - "position": [ - 1400, - 0 - ], - "inputs": { - "input": "{FeatureExtraction_1.input}", - "featuresFolders": [ - "{FeatureExtraction_1.output}" - ], - "method": "FrustumOrVocabularyTree" - } - }, - "LdrToHdrCalibration_1": { - "nodeType": "LdrToHdrCalibration", - "position": [ - 600, - 0 - ], - "inputs": { - "input": "{LdrToHdrSampling_1.input}", - "samples": "{LdrToHdrSampling_1.output}", - "userNbBrackets": "{LdrToHdrSampling_1.userNbBrackets}", - "byPass": "{LdrToHdrSampling_1.byPass}", - "calibrationMethod": "{LdrToHdrSampling_1.calibrationMethod}", - "channelQuantizationPower": "{LdrToHdrSampling_1.channelQuantizationPower}", - "workingColorSpace": "{LdrToHdrSampling_1.workingColorSpace}" - } - }, - "LdrToHdrMerge_1": { - "nodeType": "LdrToHdrMerge", - "position": [ - 800, - 0 - ], - "inputs": { - "input": "{LdrToHdrCalibration_1.input}", - "response": "{LdrToHdrCalibration_1.response}", - "userNbBrackets": "{LdrToHdrCalibration_1.userNbBrackets}", - "byPass": "{LdrToHdrCalibration_1.byPass}", - "channelQuantizationPower": "{LdrToHdrCalibration_1.channelQuantizationPower}", - "workingColorSpace": "{LdrToHdrCalibration_1.workingColorSpace}" - } - }, - "LdrToHdrSampling_1": { - "nodeType": "LdrToHdrSampling", - "position": [ - 400, - 0 - ], - "inputs": { - "input": "{PanoramaPrepareImages_1.output}" - } - }, - "PanoramaCompositing_1": { - "nodeType": "PanoramaCompositing", - "position": [ - 2600, - 0 - ], - "inputs": { - "input": "{PanoramaSeams_1.outputSfm}", - "warpingFolder": "{PanoramaSeams_1.warpingFolder}", - "labels": "{PanoramaSeams_1.output}", - "useTiling": false - } - }, - "PanoramaEstimation_1": { - "nodeType": "PanoramaEstimation", - "position": [ - 1800, - 0 - ], - "inputs": { - "input": "{FeatureMatching_1.input}", - "featuresFolders": "{FeatureMatching_1.featuresFolders}", - "matchesFolders": [ - "{FeatureMatching_1.output}" - ], - "describerTypes": "{FeatureMatching_1.describerTypes}" - } - }, - "PanoramaInit_1": { - "nodeType": "PanoramaInit", - "position": [ - 1000, - 0 - ], - "inputs": { - "input": "{LdrToHdrMerge_1.outSfMData}", - "useFisheye": true - } - }, - "PanoramaMerging_1": { - "nodeType": "PanoramaMerging", - "position": [ - 2800, - 0 - ], - "inputs": { - "input": "{PanoramaCompositing_1.input}", - "compositingFolder": "{PanoramaCompositing_1.output}", - "useTiling": "{PanoramaCompositing_1.useTiling}" - } - }, - "PanoramaPostProcessing_1": { - "nodeType": "PanoramaPostProcessing", - "position": [ - 3000, - 0 - ], - "inputs": { - "inputPanorama": "{PanoramaMerging_1.outputPanorama}", - "fillHoles": true - } - }, - "PanoramaPrepareImages_1": { - "nodeType": "PanoramaPrepareImages", - "position": [ - 200, - 0 - ], - "inputs": { - "input": "{CameraInit_1.output}" - } - }, - "PanoramaSeams_1": { - "nodeType": "PanoramaSeams", - "position": [ - 2400, - 0 - ], - "inputs": { - "input": "{PanoramaWarping_1.input}", - "warpingFolder": "{PanoramaWarping_1.output}" - } - }, - "PanoramaWarping_1": { - "nodeType": "PanoramaWarping", - "position": [ - 2200, - 0 - ], - "inputs": { - "input": "{SfMTransform_1.output}" - } - }, - "Publish_1": { - "nodeType": "Publish", - "position": [ - 3200, - 0 - ], - "inputs": { - "inputFiles": [ - "{PanoramaPostProcessing_1.outputPanorama}", - "{PanoramaPostProcessing_1.outputPanoramaPreview}", - "{PanoramaPostProcessing_1.downscaledPanoramaLevels}" - ] - } - }, - "SfMTransform_1": { - "nodeType": "SfMTransform", - "position": [ - 2000, - 0 - ], - "inputs": { - "input": "{PanoramaEstimation_1.output}", - "method": "manual" - } - } - } -} \ No newline at end of file diff --git a/meshroom/pipelines/panoramaHdr.mg b/meshroom/pipelines/panoramaHdr.mg deleted file mode 100644 index 566c126d15..0000000000 --- a/meshroom/pipelines/panoramaHdr.mg +++ /dev/null @@ -1,233 +0,0 @@ -{ - "header": { - "nodesVersions": { - "CameraInit": "12.0", - "FeatureExtraction": "1.3", - "FeatureMatching": "2.0", - "ImageMatching": "2.0", - "LdrToHdrCalibration": "3.1", - "LdrToHdrMerge": "4.1", - "LdrToHdrSampling": "4.0", - "PanoramaCompositing": "2.0", - "PanoramaEstimation": "1.0", - "PanoramaInit": "2.0", - "PanoramaMerging": "1.0", - "PanoramaPostProcessing": "2.0", - "PanoramaPrepareImages": "1.1", - "PanoramaSeams": "2.0", - "PanoramaWarping": "1.1", - "Publish": "1.3", - "SfMTransform": "3.1" - }, - "releaseVersion": "2025.1.0-develop", - "fileVersion": "2.0", - "template": true - }, - "graph": { - "CameraInit_1": { - "nodeType": "CameraInit", - "position": [ - 0, - 0 - ], - "inputs": {} - }, - "FeatureExtraction_1": { - "nodeType": "FeatureExtraction", - "position": [ - 1000, - 70 - ], - "inputs": { - "input": "{LdrToHdrMerge_1.outSfMData}", - "describerQuality": "high" - } - }, - "FeatureMatching_1": { - "nodeType": "FeatureMatching", - "position": [ - 1400, - 0 - ], - "inputs": { - "input": "{ImageMatching_1.input}", - "featuresFolders": "{ImageMatching_1.featuresFolders}", - "imagePairsList": "{ImageMatching_1.output}", - "describerTypes": "{FeatureExtraction_1.describerTypes}", - "minRequired2DMotion": 5.0 - } - }, - "ImageMatching_1": { - "nodeType": "ImageMatching", - "position": [ - 1200, - 0 - ], - "inputs": { - "input": "{PanoramaInit_1.outSfMData}", - "featuresFolders": [ - "{FeatureExtraction_1.output}" - ], - "method": "FrustumOrVocabularyTree" - } - }, - "LdrToHdrCalibration_1": { - "nodeType": "LdrToHdrCalibration", - "position": [ - 600, - 0 - ], - "inputs": { - "input": "{LdrToHdrSampling_1.input}", - "samples": "{LdrToHdrSampling_1.output}", - "userNbBrackets": "{LdrToHdrSampling_1.userNbBrackets}", - "byPass": "{LdrToHdrSampling_1.byPass}", - "calibrationMethod": "{LdrToHdrSampling_1.calibrationMethod}", - "channelQuantizationPower": "{LdrToHdrSampling_1.channelQuantizationPower}", - "workingColorSpace": "{LdrToHdrSampling_1.workingColorSpace}" - } - }, - "LdrToHdrMerge_1": { - "nodeType": "LdrToHdrMerge", - "position": [ - 800, - 0 - ], - "inputs": { - "input": "{LdrToHdrCalibration_1.input}", - "response": "{LdrToHdrCalibration_1.response}", - "userNbBrackets": "{LdrToHdrCalibration_1.userNbBrackets}", - "byPass": "{LdrToHdrCalibration_1.byPass}", - "channelQuantizationPower": "{LdrToHdrCalibration_1.channelQuantizationPower}", - "workingColorSpace": "{LdrToHdrCalibration_1.workingColorSpace}" - } - }, - "LdrToHdrSampling_1": { - "nodeType": "LdrToHdrSampling", - "position": [ - 400, - 0 - ], - "inputs": { - "input": "{PanoramaPrepareImages_1.output}" - } - }, - "PanoramaCompositing_1": { - "nodeType": "PanoramaCompositing", - "position": [ - 2400, - 0 - ], - "inputs": { - "input": "{PanoramaSeams_1.outputSfm}", - "warpingFolder": "{PanoramaSeams_1.warpingFolder}", - "labels": "{PanoramaSeams_1.output}" - } - }, - "PanoramaEstimation_1": { - "nodeType": "PanoramaEstimation", - "position": [ - 1600, - 0 - ], - "inputs": { - "input": "{FeatureMatching_1.input}", - "featuresFolders": "{FeatureMatching_1.featuresFolders}", - "matchesFolders": [ - "{FeatureMatching_1.output}" - ], - "describerTypes": "{FeatureMatching_1.describerTypes}" - } - }, - "PanoramaInit_1": { - "nodeType": "PanoramaInit", - "position": [ - 1000, - -50 - ], - "inputs": { - "input": "{LdrToHdrMerge_1.outSfMData}" - } - }, - "PanoramaMerging_1": { - "nodeType": "PanoramaMerging", - "position": [ - 2600, - 0 - ], - "inputs": { - "input": "{PanoramaCompositing_1.input}", - "compositingFolder": "{PanoramaCompositing_1.output}", - "useTiling": "{PanoramaCompositing_1.useTiling}" - } - }, - "PanoramaPostProcessing_1": { - "nodeType": "PanoramaPostProcessing", - "position": [ - 2800, - 0 - ], - "inputs": { - "inputPanorama": "{PanoramaMerging_1.outputPanorama}", - "fillHoles": true, - "exportLevels": true - } - }, - "PanoramaPrepareImages_1": { - "nodeType": "PanoramaPrepareImages", - "position": [ - 200, - 0 - ], - "inputs": { - "input": "{CameraInit_1.output}" - } - }, - "PanoramaSeams_1": { - "nodeType": "PanoramaSeams", - "position": [ - 2200, - 0 - ], - "inputs": { - "input": "{PanoramaWarping_1.input}", - "warpingFolder": "{PanoramaWarping_1.output}" - } - }, - "PanoramaWarping_1": { - "nodeType": "PanoramaWarping", - "position": [ - 2000, - 0 - ], - "inputs": { - "input": "{SfMTransform_1.output}" - } - }, - "Publish_1": { - "nodeType": "Publish", - "position": [ - 3000, - 0 - ], - "inputs": { - "inputFiles": [ - "{PanoramaPostProcessing_1.outputPanorama}", - "{PanoramaPostProcessing_1.outputPanoramaPreview}", - "{PanoramaPostProcessing_1.downscaledPanoramaLevels}" - ] - } - }, - "SfMTransform_1": { - "nodeType": "SfMTransform", - "position": [ - 1800, - 0 - ], - "inputs": { - "input": "{PanoramaEstimation_1.output}", - "method": "manual" - } - } - } -} \ No newline at end of file diff --git a/meshroom/pipelines/photogrammetry.mg b/meshroom/pipelines/photogrammetry.mg deleted file mode 100644 index 8290fbb384..0000000000 --- a/meshroom/pipelines/photogrammetry.mg +++ /dev/null @@ -1,161 +0,0 @@ -{ - "header": { - "releaseVersion": "2025.1.0-develop", - "fileVersion": "2.0", - "template": true, - "nodesVersions": { - "CameraInit": "12.0", - "DepthMap": "5.0", - "DepthMapFilter": "4.0", - "FeatureExtraction": "1.3", - "FeatureMatching": "2.0", - "ImageMatching": "2.0", - "MeshFiltering": "3.0", - "Meshing": "7.0", - "PrepareDenseScene": "3.1", - "Publish": "1.3", - "StructureFromMotion": "3.3", - "Texturing": "6.0" - } - }, - "graph": { - "CameraInit_1": { - "nodeType": "CameraInit", - "position": [ - 0, - 0 - ], - "inputs": {} - }, - "DepthMapFilter_1": { - "nodeType": "DepthMapFilter", - "position": [ - 1400, - 0 - ], - "inputs": { - "input": "{DepthMap_1.input}", - "depthMapsFolder": "{DepthMap_1.output}" - } - }, - "DepthMap_1": { - "nodeType": "DepthMap", - "position": [ - 1200, - 0 - ], - "inputs": { - "input": "{PrepareDenseScene_1.input}", - "imagesFolder": "{PrepareDenseScene_1.output}" - } - }, - "FeatureExtraction_1": { - "nodeType": "FeatureExtraction", - "position": [ - 200, - 0 - ], - "inputs": { - "input": "{CameraInit_1.output}" - } - }, - "FeatureMatching_1": { - "nodeType": "FeatureMatching", - "position": [ - 600, - 0 - ], - "inputs": { - "input": "{ImageMatching_1.input}", - "featuresFolders": "{ImageMatching_1.featuresFolders}", - "imagePairsList": "{ImageMatching_1.output}", - "describerTypes": "{FeatureExtraction_1.describerTypes}" - } - }, - "ImageMatching_1": { - "nodeType": "ImageMatching", - "position": [ - 400, - 0 - ], - "inputs": { - "input": "{FeatureExtraction_1.input}", - "featuresFolders": [ - "{FeatureExtraction_1.output}" - ] - } - }, - "MeshFiltering_1": { - "nodeType": "MeshFiltering", - "position": [ - 1800, - 0 - ], - "inputs": { - "inputMesh": "{Meshing_1.outputMesh}" - } - }, - "Meshing_1": { - "nodeType": "Meshing", - "position": [ - 1600, - 0 - ], - "inputs": { - "input": "{DepthMapFilter_1.input}", - "depthMapsFolder": "{DepthMapFilter_1.output}" - } - }, - "PrepareDenseScene_1": { - "nodeType": "PrepareDenseScene", - "position": [ - 1000, - 0 - ], - "inputs": { - "input": "{StructureFromMotion_1.output}" - } - }, - "Publish_1": { - "nodeType": "Publish", - "position": [ - 2200, - 0 - ], - "inputs": { - "inputFiles": [ - "{Texturing_1.outputMesh}", - "{Texturing_1.outputMaterial}", - "{Texturing_1.outputTextures}" - ] - } - }, - "StructureFromMotion_1": { - "nodeType": "StructureFromMotion", - "position": [ - 800, - 0 - ], - "inputs": { - "input": "{FeatureMatching_1.input}", - "featuresFolders": "{FeatureMatching_1.featuresFolders}", - "matchesFolders": [ - "{FeatureMatching_1.output}" - ], - "describerTypes": "{FeatureMatching_1.describerTypes}" - } - }, - "Texturing_1": { - "nodeType": "Texturing", - "position": [ - 2000, - 0 - ], - "inputs": { - "input": "{Meshing_1.output}", - "imagesFolder": "{DepthMap_1.imagesFolder}", - "inputMesh": "{MeshFiltering_1.outputMesh}" - } - } - } -} \ No newline at end of file diff --git a/meshroom/pipelines/photogrammetryAndCameraTracking.mg b/meshroom/pipelines/photogrammetryAndCameraTracking.mg deleted file mode 100644 index aa32aa9770..0000000000 --- a/meshroom/pipelines/photogrammetryAndCameraTracking.mg +++ /dev/null @@ -1,605 +0,0 @@ -{ - "header": { - "releaseVersion": "2025.1.0-develop", - "fileVersion": "2.0", - "template": true, - "nodesVersions": { - "ApplyCalibration": "1.0", - "CameraInit": "12.0", - "CheckerboardDetection": "1.0", - "ConvertSfMFormat": "2.0", - "DepthMap": "5.0", - "DepthMapFilter": "4.0", - "DistortionCalibration": "5.0", - "ExportAnimatedCamera": "2.0", - "ExportDistortion": "2.0", - "FeatureExtraction": "1.3", - "FeatureMatching": "2.0", - "ImageDetectionPrompt": "0.1", - "ImageMatching": "2.0", - "ImageMatchingMultiSfM": "1.0", - "ImageSegmentationBox": "0.1", - "KeyframeSelection": "5.0", - "MeshDecimate": "1.0", - "MeshFiltering": "3.0", - "Meshing": "7.0", - "PrepareDenseScene": "3.1", - "Publish": "1.3", - "ScenePreview": "2.0", - "StructureFromMotion": "3.3", - "Texturing": "6.0" - } - }, - "graph": { - "ApplyCalibration_1": { - "nodeType": "ApplyCalibration", - "position": [ - 0, - 0 - ], - "inputs": { - "input": "{CameraInit_1.output}", - "calibration": "{DistortionCalibration_1.output}" - }, - "internalInputs": { - "color": "#575963" - } - }, - "CameraInit_1": { - "nodeType": "CameraInit", - "position": [ - -200, - 0 - ], - "inputs": {}, - "internalInputs": { - "label": "InitShot", - "color": "#575963" - } - }, - "CameraInit_2": { - "nodeType": "CameraInit", - "position": [ - -600, - -160 - ], - "inputs": {}, - "internalInputs": { - "label": "InitLensGrid", - "color": "#302e2e" - } - }, - "CameraInit_3": { - "nodeType": "CameraInit", - "position": [ - -600, - -500 - ], - "inputs": {}, - "internalInputs": { - "label": "InitPhotogrammetry", - "color": "#384a55" - } - }, - "CheckerboardDetection_1": { - "nodeType": "CheckerboardDetection", - "position": [ - -400, - -160 - ], - "inputs": { - "input": "{CameraInit_2.output}", - "useNestedGrids": true, - "exportDebugImages": true - }, - "internalInputs": { - "color": "#302e2e" - } - }, - "ConvertSfMFormat_1": { - "nodeType": "ConvertSfMFormat", - "position": [ - 2000, - 200 - ], - "inputs": { - "input": "{ExportAnimatedCamera_1.input}", - "fileExt": "sfm", - "describerTypes": "{StructureFromMotion_1.describerTypes}", - "structure": false, - "observations": false - }, - "internalInputs": { - "color": "#4c594c" - } - }, - "DepthMapFilter_2": { - "nodeType": "DepthMapFilter", - "position": [ - 800, - -500 - ], - "inputs": { - "input": "{DepthMap_2.input}", - "depthMapsFolder": "{DepthMap_2.output}" - }, - "internalInputs": { - "color": "#384a55" - } - }, - "DepthMap_2": { - "nodeType": "DepthMap", - "position": [ - 600, - -500 - ], - "inputs": { - "input": "{PrepareDenseScene_2.input}", - "imagesFolder": "{PrepareDenseScene_2.output}" - }, - "internalInputs": { - "color": "#384a55" - } - }, - "DistortionCalibration_1": { - "nodeType": "DistortionCalibration", - "position": [ - -200, - -160 - ], - "inputs": { - "input": "{CheckerboardDetection_1.input}", - "checkerboards": "{CheckerboardDetection_1.output}" - }, - "internalInputs": { - "color": "#302e2e" - } - }, - "ExportAnimatedCamera_1": { - "nodeType": "ExportAnimatedCamera", - "position": [ - 1600, - 200 - ], - "inputs": { - "input": "{StructureFromMotion_1.output}", - "sfmDataFilter": "{ImageMatchingMultiSfM_2.inputB}", - "exportUndistortedImages": true - }, - "internalInputs": { - "color": "#80766f" - } - }, - "ExportDistortion_1": { - "nodeType": "ExportDistortion", - "position": [ - 0, - -160 - ], - "inputs": { - "input": "{DistortionCalibration_1.output}" - }, - "internalInputs": { - "color": "#302e2e" - } - }, - "FeatureExtraction_1": { - "nodeType": "FeatureExtraction", - "position": [ - 400, - 200 - ], - "inputs": { - "input": "{ApplyCalibration_1.output}", - "masksFolder": "{ImageSegmentationBox_2.output}", - "maskExtension": "exr" - }, - "internalInputs": { - "color": "#575963" - } - }, - "FeatureExtraction_2": { - "nodeType": "FeatureExtraction", - "position": [ - -400, - -500 - ], - "inputs": { - "input": "{CameraInit_3.output}" - }, - "internalInputs": { - "color": "#384a55" - } - }, - "FeatureMatching_1": { - "nodeType": "FeatureMatching", - "position": [ - 600, - 0 - ], - "inputs": { - "input": "{ImageMatching_1.input}", - "featuresFolders": "{ImageMatching_1.featuresFolders}", - "imagePairsList": "{ImageMatching_1.output}", - "describerTypes": "{FeatureExtraction_1.describerTypes}" - }, - "internalInputs": { - "label": "FeatureMatchingKeyframes", - "color": "#575963" - } - }, - "FeatureMatching_2": { - "nodeType": "FeatureMatching", - "position": [ - 1200, - 360 - ], - "inputs": { - "input": "{ImageMatching_2.input}", - "featuresFolders": "{ImageMatching_2.featuresFolders}", - "imagePairsList": "{ImageMatching_2.output}" - }, - "internalInputs": { - "label": "FeatureMatchingAllFrames", - "color": "#80766f" - } - }, - "FeatureMatching_3": { - "nodeType": "FeatureMatching", - "position": [ - 1200, - 200 - ], - "inputs": { - "input": "{ImageMatchingMultiSfM_1.outputCombinedSfM}", - "featuresFolders": "{ImageMatchingMultiSfM_1.featuresFolders}", - "imagePairsList": "{ImageMatchingMultiSfM_1.output}", - "describerTypes": "{FeatureExtraction_1.describerTypes}" - }, - "internalInputs": { - "label": "FeatureMatchingFramesToKeyframes", - "color": "#80766f" - } - }, - "FeatureMatching_4": { - "nodeType": "FeatureMatching", - "position": [ - 0, - -500 - ], - "inputs": { - "input": "{ImageMatching_3.input}", - "featuresFolders": "{ImageMatching_3.featuresFolders}", - "imagePairsList": "{ImageMatching_3.output}", - "describerTypes": "{FeatureExtraction_2.describerTypes}" - }, - "internalInputs": { - "color": "#384a55" - } - }, - "FeatureMatching_5": { - "nodeType": "FeatureMatching", - "position": [ - 600, - -300 - ], - "inputs": { - "input": "{ImageMatchingMultiSfM_2.outputCombinedSfM}", - "featuresFolders": "{ImageMatchingMultiSfM_2.featuresFolders}", - "imagePairsList": "{ImageMatchingMultiSfM_2.output}", - "describerTypes": "{FeatureExtraction_1.describerTypes}" - }, - "internalInputs": { - "color": "#575963" - } - }, - "ImageDetectionPrompt_1": { - "nodeType": "ImageDetectionPrompt", - "position": [ - 0, - 200 - ], - "inputs": { - "input": "{CameraInit_1.output}" - }, - "internalInputs": { - "color": "#575963" - } - }, - "ImageMatchingMultiSfM_1": { - "nodeType": "ImageMatchingMultiSfM", - "position": [ - 1000, - 200 - ], - "inputs": { - "input": "{KeyframeSelection_1.outputSfMDataFrames}", - "inputB": "{StructureFromMotion_2.output}", - "featuresFolders": [ - "{FeatureExtraction_1.output}" - ], - "method": "VocabularyTree", - "matchingMode": "a/b", - "nbMatches": 20 - }, - "internalInputs": { - "color": "#80766f" - } - }, - "ImageMatchingMultiSfM_2": { - "nodeType": "ImageMatchingMultiSfM", - "position": [ - 400, - -300 - ], - "inputs": { - "input": "{KeyframeSelection_1.outputSfMDataKeyframes}", - "inputB": "{StructureFromMotion_3.output}", - "featuresFolders": [ - "{FeatureExtraction_1.output}" - ], - "method": "Exhaustive", - "matchingMode": "a/b" - }, - "internalInputs": { - "color": "#575963" - } - }, - "ImageMatching_1": { - "nodeType": "ImageMatching", - "position": [ - 400, - 0 - ], - "inputs": { - "input": "{KeyframeSelection_1.outputSfMDataKeyframes}", - "featuresFolders": [ - "{FeatureExtraction_1.output}" - ], - "method": "Exhaustive" - }, - "internalInputs": { - "label": "ImageMatchingKeyframes", - "color": "#575963" - } - }, - "ImageMatching_2": { - "nodeType": "ImageMatching", - "position": [ - 1000, - 360 - ], - "inputs": { - "input": "{ApplyCalibration_1.output}", - "featuresFolders": [ - "{FeatureExtraction_1.output}" - ], - "method": "Sequential", - "nbNeighbors": 20 - }, - "internalInputs": { - "color": "#80766f" - } - }, - "ImageMatching_3": { - "nodeType": "ImageMatching", - "position": [ - -200, - -500 - ], - "inputs": { - "input": "{FeatureExtraction_2.input}", - "featuresFolders": [ - "{FeatureExtraction_2.output}" - ] - }, - "internalInputs": { - "color": "#384a55" - } - }, - "ImageSegmentationBox_2": { - "nodeType": "ImageSegmentationBox", - "position": [ - 200, - 200 - ], - "inputs": { - "input": "{ImageDetectionPrompt_1.input}", - "bboxFolder": "{ImageDetectionPrompt_1.output}", - "maskInvert": true, - "keepFilename": true - }, - "internalInputs": { - "color": "#575963" - } - }, - "KeyframeSelection_1": { - "nodeType": "KeyframeSelection", - "position": [ - 200, - 0 - ], - "inputs": { - "inputPaths": [ - "{ApplyCalibration_1.output}" - ] - }, - "internalInputs": { - "color": "#575963" - } - }, - "MeshDecimate_1": { - "nodeType": "MeshDecimate", - "position": [ - 2000, - 100 - ], - "inputs": { - "input": "{MeshFiltering_2.outputMesh}", - "simplificationFactor": 0.05 - }, - "internalInputs": { - "color": "#4c594c" - } - }, - "MeshFiltering_2": { - "nodeType": "MeshFiltering", - "position": [ - 1200, - -500 - ], - "inputs": { - "inputMesh": "{Meshing_2.outputMesh}" - }, - "internalInputs": { - "color": "#384a55" - } - }, - "Meshing_2": { - "nodeType": "Meshing", - "position": [ - 1000, - -500 - ], - "inputs": { - "input": "{DepthMapFilter_2.input}", - "depthMapsFolder": "{DepthMapFilter_2.output}" - }, - "internalInputs": { - "color": "#384a55" - } - }, - "PrepareDenseScene_2": { - "nodeType": "PrepareDenseScene", - "position": [ - 400, - -500 - ], - "inputs": { - "input": "{StructureFromMotion_3.output}" - }, - "internalInputs": { - "color": "#384a55" - } - }, - "Publish_1": { - "nodeType": "Publish", - "position": [ - 2400, - -100 - ], - "inputs": { - "inputFiles": [ - "{ExportAnimatedCamera_1.output}", - "{ScenePreview_1.output}", - "{ExportDistortion_1.output}", - "{Texturing_2.output}" - ] - } - }, - "ScenePreview_1": { - "nodeType": "ScenePreview", - "position": [ - 2200, - 200 - ], - "inputs": { - "cameras": "{ConvertSfMFormat_1.output}", - "model": "{MeshDecimate_1.output}", - "undistortedImages": "{ExportAnimatedCamera_1.outputUndistorted}", - "masks": "{ImageSegmentationBox_2.output}" - }, - "internalInputs": { - "color": "#4c594c" - } - }, - "StructureFromMotion_1": { - "nodeType": "StructureFromMotion", - "position": [ - 1400, - 200 - ], - "inputs": { - "input": "{FeatureMatching_3.input}", - "featuresFolders": "{FeatureMatching_3.featuresFolders}", - "matchesFolders": [ - "{FeatureMatching_3.output}", - "{FeatureMatching_2.output}" - ], - "describerTypes": "{FeatureMatching_3.describerTypes}", - "nbFirstUnstableCameras": 0, - "maxImagesPerGroup": 0, - "bundleAdjustmentMaxOutliers": -1, - "minInputTrackLength": 5, - "minNumberOfObservationsForTriangulation": 3, - "minAngleForTriangulation": 1.0, - "minAngleForLandmark": 0.5, - "filterTrackForks": true, - "useAutoTransform": false - }, - "internalInputs": { - "comment": "Estimate cameras parameters for the complete camera tracking sequence.", - "color": "#80766f" - } - }, - "StructureFromMotion_2": { - "nodeType": "StructureFromMotion", - "position": [ - 800, - 0 - ], - "inputs": { - "input": "{FeatureMatching_5.input}", - "featuresFolders": "{FeatureMatching_1.featuresFolders}", - "matchesFolders": [ - "{FeatureMatching_1.output}", - "{FeatureMatching_5.output}" - ], - "describerTypes": "{FeatureMatching_1.describerTypes}", - "lockScenePreviouslyReconstructed": true, - "minAngleForTriangulation": 1.0, - "minAngleForLandmark": 0.5, - "filterTrackForks": true, - "useAutoTransform": false - }, - "internalInputs": { - "comment": "Solve all keyframes first.", - "label": "StructureFromMotionKeyframes", - "color": "#575963" - } - }, - "StructureFromMotion_3": { - "nodeType": "StructureFromMotion", - "position": [ - 200, - -500 - ], - "inputs": { - "input": "{FeatureMatching_4.input}", - "featuresFolders": "{FeatureMatching_4.featuresFolders}", - "matchesFolders": [ - "{FeatureMatching_4.output}" - ], - "describerTypes": "{FeatureMatching_4.describerTypes}" - }, - "internalInputs": { - "color": "#384a55" - } - }, - "Texturing_2": { - "nodeType": "Texturing", - "position": [ - 1400, - -500 - ], - "inputs": { - "input": "{Meshing_2.output}", - "imagesFolder": "{DepthMap_2.imagesFolder}", - "inputMesh": "{MeshFiltering_2.outputMesh}" - }, - "internalInputs": { - "color": "#384a55" - } - } - } -} \ No newline at end of file diff --git a/meshroom/pipelines/photogrammetryAndCameraTrackingExperimental.mg b/meshroom/pipelines/photogrammetryAndCameraTrackingExperimental.mg deleted file mode 100644 index 93cf7215ad..0000000000 --- a/meshroom/pipelines/photogrammetryAndCameraTrackingExperimental.mg +++ /dev/null @@ -1,712 +0,0 @@ -{ - "header": { - "releaseVersion": "2025.1.0-develop", - "fileVersion": "2.0", - "nodesVersions": { - "ApplyCalibration": "1.0", - "CameraInit": "12.0", - "CheckerboardDetection": "1.0", - "ConvertSfMFormat": "2.0", - "DepthMap": "5.0", - "DepthMapFilter": "4.0", - "DistortionCalibration": "5.0", - "ExportAnimatedCamera": "2.0", - "ExportDistortion": "2.0", - "FeatureExtraction": "1.3", - "FeatureMatching": "2.0", - "ImageDetectionPrompt": "0.1", - "ImageMatching": "2.0", - "ImageMatchingMultiSfM": "1.0", - "ImageSegmentationBox": "0.1", - "KeyframeSelection": "5.0", - "MeshDecimate": "1.0", - "MeshFiltering": "3.0", - "Meshing": "7.0", - "PrepareDenseScene": "3.1", - "Publish": "1.3", - "RelativePoseEstimating": "3.0", - "ScenePreview": "2.0", - "SfMBootStraping": "3.0", - "SfMExpanding": "2.0", - "Texturing": "6.0", - "TracksBuilding": "1.0" - }, - "template": true - }, - "graph": { - "ApplyCalibration_1": { - "nodeType": "ApplyCalibration", - "position": [ - 0, - 0 - ], - "inputs": { - "input": "{CameraInit_1.output}", - "calibration": "{DistortionCalibration_1.output}" - }, - "internalInputs": { - "color": "#575963" - } - }, - "CameraInit_1": { - "nodeType": "CameraInit", - "position": [ - -200, - 0 - ], - "inputs": {}, - "internalInputs": { - "label": "InitShot", - "color": "#575963" - } - }, - "CameraInit_2": { - "nodeType": "CameraInit", - "position": [ - -600, - -160 - ], - "inputs": {}, - "internalInputs": { - "label": "InitLensGrid", - "color": "#302e2e" - } - }, - "CameraInit_3": { - "nodeType": "CameraInit", - "position": [ - -600, - -500 - ], - "inputs": {}, - "internalInputs": { - "label": "InitPhotogrammetry", - "color": "#384a55" - } - }, - "CheckerboardDetection_1": { - "nodeType": "CheckerboardDetection", - "position": [ - -400, - -160 - ], - "inputs": { - "input": "{CameraInit_2.output}", - "useNestedGrids": true, - "exportDebugImages": true - }, - "internalInputs": { - "color": "#302e2e" - } - }, - "ConvertSfMFormat_1": { - "nodeType": "ConvertSfMFormat", - "position": [ - 2600, - 200 - ], - "inputs": { - "input": "{ExportAnimatedCamera_1.input}", - "fileExt": "sfm", - "describerTypes": "{TracksBuilding_3.describerTypes}", - "structure": false, - "observations": false - }, - "internalInputs": { - "color": "#4c594c" - } - }, - "DepthMapFilter_2": { - "nodeType": "DepthMapFilter", - "position": [ - 1400, - -500 - ], - "inputs": { - "input": "{DepthMap_2.input}", - "depthMapsFolder": "{DepthMap_2.output}" - }, - "internalInputs": { - "color": "#384a55" - } - }, - "DepthMap_2": { - "nodeType": "DepthMap", - "position": [ - 1200, - -500 - ], - "inputs": { - "input": "{PrepareDenseScene_2.input}", - "imagesFolder": "{PrepareDenseScene_2.output}" - }, - "internalInputs": { - "color": "#384a55" - } - }, - "DistortionCalibration_1": { - "nodeType": "DistortionCalibration", - "position": [ - -200, - -160 - ], - "inputs": { - "input": "{CheckerboardDetection_1.input}", - "checkerboards": "{CheckerboardDetection_1.output}" - }, - "internalInputs": { - "color": "#302e2e" - } - }, - "ExportAnimatedCamera_1": { - "nodeType": "ExportAnimatedCamera", - "position": [ - 2400, - 200 - ], - "inputs": { - "input": "{SfMExpanding_3.output}", - "sfmDataFilter": "{ImageMatchingMultiSfM_2.inputB}", - "exportUndistortedImages": true - }, - "internalInputs": { - "color": "#80766f" - } - }, - "ExportDistortion_1": { - "nodeType": "ExportDistortion", - "position": [ - 0, - -160 - ], - "inputs": { - "input": "{DistortionCalibration_1.output}" - }, - "internalInputs": { - "color": "#302e2e" - } - }, - "FeatureExtraction_1": { - "nodeType": "FeatureExtraction", - "position": [ - 400, - 200 - ], - "inputs": { - "input": "{ApplyCalibration_1.output}", - "masksFolder": "{ImageSegmentationBox_2.output}", - "maskExtension": "exr" - }, - "internalInputs": { - "color": "#575963" - } - }, - "FeatureExtraction_2": { - "nodeType": "FeatureExtraction", - "position": [ - -400, - -500 - ], - "inputs": { - "input": "{CameraInit_3.output}" - }, - "internalInputs": { - "color": "#384a55" - } - }, - "FeatureMatching_1": { - "nodeType": "FeatureMatching", - "position": [ - 600, - 0 - ], - "inputs": { - "input": "{ImageMatching_1.input}", - "featuresFolders": "{ImageMatching_1.featuresFolders}", - "imagePairsList": "{ImageMatching_1.output}", - "describerTypes": "{FeatureExtraction_1.describerTypes}" - }, - "internalInputs": { - "label": "FeatureMatchingKeyframes", - "color": "#575963" - } - }, - "FeatureMatching_2": { - "nodeType": "FeatureMatching", - "position": [ - 1800, - 400 - ], - "inputs": { - "input": "{ImageMatching_2.input}", - "featuresFolders": "{ImageMatching_2.featuresFolders}", - "imagePairsList": "{ImageMatching_2.output}" - }, - "internalInputs": { - "label": "FeatureMatchingAllFrames", - "color": "#80766f" - } - }, - "FeatureMatching_3": { - "nodeType": "FeatureMatching", - "position": [ - 1800, - 200 - ], - "inputs": { - "input": "{ImageMatchingMultiSfM_1.outputCombinedSfM}", - "featuresFolders": "{ImageMatchingMultiSfM_1.featuresFolders}", - "imagePairsList": "{ImageMatchingMultiSfM_1.output}", - "describerTypes": "{FeatureExtraction_1.describerTypes}" - }, - "internalInputs": { - "label": "FeatureMatchingFramesToKeyframes", - "color": "#80766f" - } - }, - "FeatureMatching_4": { - "nodeType": "FeatureMatching", - "position": [ - 0, - -500 - ], - "inputs": { - "input": "{ImageMatching_3.input}", - "featuresFolders": "{ImageMatching_3.featuresFolders}", - "imagePairsList": "{ImageMatching_3.output}", - "describerTypes": "{FeatureExtraction_2.describerTypes}" - }, - "internalInputs": { - "color": "#384a55" - } - }, - "FeatureMatching_5": { - "nodeType": "FeatureMatching", - "position": [ - 1200, - -300 - ], - "inputs": { - "input": "{ImageMatchingMultiSfM_2.outputCombinedSfM}", - "featuresFolders": "{ImageMatchingMultiSfM_2.featuresFolders}", - "imagePairsList": "{ImageMatchingMultiSfM_2.output}", - "describerTypes": "{FeatureExtraction_1.describerTypes}" - }, - "internalInputs": { - "color": "#575963" - } - }, - "ImageDetectionPrompt_1": { - "nodeType": "ImageDetectionPrompt", - "position": [ - 0, - 200 - ], - "inputs": { - "input": "{CameraInit_1.output}" - }, - "internalInputs": { - "color": "#575963" - } - }, - "ImageMatchingMultiSfM_1": { - "nodeType": "ImageMatchingMultiSfM", - "position": [ - 1600, - 200 - ], - "inputs": { - "input": "{KeyframeSelection_1.outputSfMDataFrames}", - "inputB": "{SfMExpanding_2.output}", - "featuresFolders": [ - "{FeatureExtraction_1.output}" - ], - "method": "VocabularyTree", - "matchingMode": "a/b", - "nbMatches": 20 - }, - "internalInputs": { - "color": "#80766f" - } - }, - "ImageMatchingMultiSfM_2": { - "nodeType": "ImageMatchingMultiSfM", - "position": [ - 1000, - -300 - ], - "inputs": { - "input": "{KeyframeSelection_1.outputSfMDataKeyframes}", - "inputB": "{SfMExpanding_1.output}", - "featuresFolders": [ - "{FeatureExtraction_1.output}" - ], - "method": "Exhaustive", - "matchingMode": "a/b" - }, - "internalInputs": { - "color": "#575963" - } - }, - "ImageMatching_1": { - "nodeType": "ImageMatching", - "position": [ - 400, - 0 - ], - "inputs": { - "input": "{KeyframeSelection_1.outputSfMDataKeyframes}", - "featuresFolders": [ - "{FeatureExtraction_1.output}" - ], - "method": "Exhaustive" - }, - "internalInputs": { - "label": "ImageMatchingKeyframes", - "color": "#575963" - } - }, - "ImageMatching_2": { - "nodeType": "ImageMatching", - "position": [ - 1600, - 400 - ], - "inputs": { - "input": "{ApplyCalibration_1.output}", - "featuresFolders": [ - "{FeatureExtraction_1.output}" - ], - "method": "Sequential", - "nbNeighbors": 20 - }, - "internalInputs": { - "color": "#80766f" - } - }, - "ImageMatching_3": { - "nodeType": "ImageMatching", - "position": [ - -200, - -500 - ], - "inputs": { - "input": "{FeatureExtraction_2.input}", - "featuresFolders": [ - "{FeatureExtraction_2.output}" - ] - }, - "internalInputs": { - "color": "#384a55" - } - }, - "ImageSegmentationBox_2": { - "nodeType": "ImageSegmentationBox", - "position": [ - 200, - 200 - ], - "inputs": { - "input": "{ImageDetectionPrompt_1.input}", - "bboxFolder": "{ImageDetectionPrompt_1.output}", - "maskInvert": true, - "keepFilename": true - }, - "internalInputs": { - "color": "#575963" - } - }, - "KeyframeSelection_1": { - "nodeType": "KeyframeSelection", - "position": [ - 200, - 0 - ], - "inputs": { - "inputPaths": [ - "{ApplyCalibration_1.output}" - ] - }, - "internalInputs": { - "color": "#575963" - } - }, - "MeshDecimate_1": { - "nodeType": "MeshDecimate", - "position": [ - 2600, - 0 - ], - "inputs": { - "input": "{MeshFiltering_2.outputMesh}", - "simplificationFactor": 0.05 - }, - "internalInputs": { - "color": "#4c594c" - } - }, - "MeshFiltering_2": { - "nodeType": "MeshFiltering", - "position": [ - 1800, - -500 - ], - "inputs": { - "inputMesh": "{Meshing_2.outputMesh}" - }, - "internalInputs": { - "color": "#384a55" - } - }, - "Meshing_2": { - "nodeType": "Meshing", - "position": [ - 1600, - -500 - ], - "inputs": { - "input": "{DepthMapFilter_2.input}", - "depthMapsFolder": "{DepthMapFilter_2.output}" - }, - "internalInputs": { - "color": "#384a55" - } - }, - "PrepareDenseScene_2": { - "nodeType": "PrepareDenseScene", - "position": [ - 1000, - -500 - ], - "inputs": { - "input": "{SfMExpanding_1.output}" - }, - "internalInputs": { - "color": "#384a55" - } - }, - "Publish_1": { - "nodeType": "Publish", - "position": [ - 3000, - -100 - ], - "inputs": { - "inputFiles": [ - "{ExportAnimatedCamera_1.output}", - "{ScenePreview_1.output}", - "{ExportDistortion_1.output}", - "{Texturing_2.output}" - ] - } - }, - "RelativePoseEstimating_1": { - "nodeType": "RelativePoseEstimating", - "position": [ - 400, - -500 - ], - "inputs": { - "input": "{TracksBuilding_1.input}", - "tracksFilename": "{TracksBuilding_1.output}", - "minInliers": 100 - }, - "internalInputs": { - "color": "#384a55" - } - }, - "RelativePoseEstimating_2": { - "nodeType": "RelativePoseEstimating", - "position": [ - 1000, - 0 - ], - "inputs": { - "input": "{TracksBuilding_2.input}", - "tracksFilename": "{TracksBuilding_2.output}", - "countIterations": 50000, - "minInliers": 100 - }, - "internalInputs": { - "color": "#575963" - } - }, - "ScenePreview_1": { - "nodeType": "ScenePreview", - "position": [ - 2800, - 200 - ], - "inputs": { - "cameras": "{ConvertSfMFormat_1.output}", - "model": "{MeshDecimate_1.output}", - "undistortedImages": "{ExportAnimatedCamera_1.outputUndistorted}", - "masks": "{ImageSegmentationBox_2.output}" - }, - "internalInputs": { - "color": "#4c594c" - } - }, - "SfMBootStraping_1": { - "nodeType": "SfMBootStraping", - "position": [ - 600, - -500 - ], - "inputs": { - "input": "{RelativePoseEstimating_1.input}", - "tracksFilename": "{RelativePoseEstimating_1.tracksFilename}", - "pairs": "{RelativePoseEstimating_1.output}" - }, - "internalInputs": { - "color": "#384a55" - } - }, - "SfMBootStraping_2": { - "nodeType": "SfMBootStraping", - "position": [ - 1200, - 0 - ], - "inputs": { - "input": "{RelativePoseEstimating_2.input}", - "tracksFilename": "{RelativePoseEstimating_2.tracksFilename}", - "pairs": "{RelativePoseEstimating_2.output}" - }, - "internalInputs": { - "color": "#575963" - } - }, - "SfMExpanding_1": { - "nodeType": "SfMExpanding", - "position": [ - 800, - -500 - ], - "inputs": { - "input": "{SfMBootStraping_1.output}", - "tracksFilename": "{SfMBootStraping_1.tracksFilename}", - "meshFilename": "{SfMBootStraping_1.meshFilename}" - }, - "internalInputs": { - "label": "SfMExpandingPhotog", - "color": "#384a55" - } - }, - "SfMExpanding_2": { - "nodeType": "SfMExpanding", - "position": [ - 1400, - 0 - ], - "inputs": { - "input": "{SfMBootStraping_2.output}", - "tracksFilename": "{SfMBootStraping_2.tracksFilename}", - "lockScenePreviouslyReconstructed": true, - "minAngleForTriangulation": 1.0, - "minAngleForLandmark": 0.5 - }, - "internalInputs": { - "comment": "Estimate cameras parameters for the keyframes.", - "label": "SfMExpandingKeys", - "color": "#575963" - } - }, - "SfMExpanding_3": { - "nodeType": "SfMExpanding", - "position": [ - 2200, - 200 - ], - "inputs": { - "input": "{TracksBuilding_3.input}", - "tracksFilename": "{TracksBuilding_3.output}", - "nbFirstUnstableCameras": 0, - "maxImagesPerGroup": 0, - "bundleAdjustmentMaxOutliers": 5000000, - "minNumberOfObservationsForTriangulation": 3, - "minAngleForTriangulation": 1.0, - "minAngleForLandmark": 0.5 - }, - "internalInputs": { - "comment": "Estimate cameras parameters for the complete camera tracking sequence.", - "label": "SfMExpandingAll", - "color": "#80766f" - } - }, - "Texturing_2": { - "nodeType": "Texturing", - "position": [ - 2000, - -500 - ], - "inputs": { - "input": "{Meshing_2.output}", - "imagesFolder": "{DepthMap_2.imagesFolder}", - "inputMesh": "{MeshFiltering_2.outputMesh}" - }, - "internalInputs": { - "color": "#384a55" - } - }, - "TracksBuilding_1": { - "nodeType": "TracksBuilding", - "position": [ - 200, - -500 - ], - "inputs": { - "input": "{FeatureMatching_4.input}", - "featuresFolders": "{FeatureMatching_4.featuresFolders}", - "matchesFolders": [ - "{FeatureMatching_4.output}" - ], - "describerTypes": "{FeatureMatching_4.describerTypes}" - }, - "internalInputs": { - "color": "#384a55" - } - }, - "TracksBuilding_2": { - "nodeType": "TracksBuilding", - "position": [ - 800, - 0 - ], - "inputs": { - "input": "{FeatureMatching_5.input}", - "featuresFolders": "{FeatureMatching_1.featuresFolders}", - "matchesFolders": [ - "{FeatureMatching_1.output}", - "{FeatureMatching_5.output}" - ], - "describerTypes": "{FeatureMatching_1.describerTypes}", - "filterTrackForks": true - }, - "internalInputs": { - "color": "#575963" - } - }, - "TracksBuilding_3": { - "nodeType": "TracksBuilding", - "position": [ - 2000, - 200 - ], - "inputs": { - "input": "{FeatureMatching_3.input}", - "featuresFolders": "{FeatureMatching_3.featuresFolders}", - "matchesFolders": [ - "{FeatureMatching_3.output}", - "{FeatureMatching_2.output}" - ], - "describerTypes": "{FeatureMatching_3.describerTypes}", - "minInputTrackLength": 5, - "filterTrackForks": true - }, - "internalInputs": { - "color": "#80766f" - } - } - } -} \ No newline at end of file diff --git a/meshroom/pipelines/photogrammetryDraft.mg b/meshroom/pipelines/photogrammetryDraft.mg deleted file mode 100644 index ace6962fa1..0000000000 --- a/meshroom/pipelines/photogrammetryDraft.mg +++ /dev/null @@ -1,136 +0,0 @@ -{ - "header": { - "nodesVersions": { - "CameraInit": "12.0", - "FeatureExtraction": "1.3", - "FeatureMatching": "2.0", - "ImageMatching": "2.0", - "MeshFiltering": "3.0", - "Meshing": "7.0", - "PrepareDenseScene": "3.1", - "Publish": "1.3", - "StructureFromMotion": "3.3", - "Texturing": "6.0" - }, - "releaseVersion": "2025.1.0-develop", - "fileVersion": "2.0", - "template": true - }, - "graph": { - "CameraInit_1": { - "nodeType": "CameraInit", - "position": [ - 0, - 0 - ], - "inputs": {} - }, - "FeatureExtraction_1": { - "nodeType": "FeatureExtraction", - "position": [ - 200, - 0 - ], - "inputs": { - "input": "{CameraInit_1.output}" - } - }, - "FeatureMatching_1": { - "nodeType": "FeatureMatching", - "position": [ - 600, - 0 - ], - "inputs": { - "input": "{ImageMatching_1.input}", - "featuresFolders": "{ImageMatching_1.featuresFolders}", - "imagePairsList": "{ImageMatching_1.output}", - "describerTypes": "{FeatureExtraction_1.describerTypes}" - } - }, - "ImageMatching_1": { - "nodeType": "ImageMatching", - "position": [ - 400, - 0 - ], - "inputs": { - "input": "{FeatureExtraction_1.input}", - "featuresFolders": [ - "{FeatureExtraction_1.output}" - ] - } - }, - "MeshFiltering_1": { - "nodeType": "MeshFiltering", - "position": [ - 1400, - 0 - ], - "inputs": { - "inputMesh": "{Meshing_1.outputMesh}" - } - }, - "Meshing_1": { - "nodeType": "Meshing", - "position": [ - 1200, - 0 - ], - "inputs": { - "input": "{PrepareDenseScene_1.input}" - } - }, - "PrepareDenseScene_1": { - "nodeType": "PrepareDenseScene", - "position": [ - 1000, - 0 - ], - "inputs": { - "input": "{StructureFromMotion_1.output}" - } - }, - "Publish_1": { - "nodeType": "Publish", - "position": [ - 1800, - 0 - ], - "inputs": { - "inputFiles": [ - "{Texturing_1.outputMesh}", - "{Texturing_1.outputMaterial}", - "{Texturing_1.outputTextures}" - ] - } - }, - "StructureFromMotion_1": { - "nodeType": "StructureFromMotion", - "position": [ - 800, - 0 - ], - "inputs": { - "input": "{FeatureMatching_1.input}", - "featuresFolders": "{FeatureMatching_1.featuresFolders}", - "matchesFolders": [ - "{FeatureMatching_1.output}" - ], - "describerTypes": "{FeatureMatching_1.describerTypes}" - } - }, - "Texturing_1": { - "nodeType": "Texturing", - "position": [ - 1600, - 0 - ], - "inputs": { - "input": "{Meshing_1.output}", - "imagesFolder": "{PrepareDenseScene_1.output}", - "inputMesh": "{MeshFiltering_1.outputMesh}" - } - } - } -} \ No newline at end of file diff --git a/meshroom/pipelines/photogrammetryExperimental.mg b/meshroom/pipelines/photogrammetryExperimental.mg deleted file mode 100644 index 01ed019621..0000000000 --- a/meshroom/pipelines/photogrammetryExperimental.mg +++ /dev/null @@ -1,200 +0,0 @@ -{ - "header": { - "releaseVersion": "2025.1.0-develop", - "fileVersion": "2.0", - "template": true, - "nodesVersions": { - "CameraInit": "12.0", - "DepthMap": "5.0", - "DepthMapFilter": "4.0", - "FeatureExtraction": "1.3", - "FeatureMatching": "2.0", - "ImageMatching": "2.0", - "MeshFiltering": "3.0", - "Meshing": "7.0", - "PrepareDenseScene": "3.1", - "Publish": "1.3", - "RelativePoseEstimating": "3.0", - "SfMBootStraping": "3.0", - "SfMExpanding": "2.0", - "Texturing": "6.0", - "TracksBuilding": "1.0" - } - }, - "graph": { - "CameraInit_1": { - "nodeType": "CameraInit", - "position": [ - 0, - 0 - ], - "inputs": {} - }, - "DepthMapFilter_1": { - "nodeType": "DepthMapFilter", - "position": [ - 2000, - 0 - ], - "inputs": { - "input": "{DepthMap_1.input}", - "depthMapsFolder": "{DepthMap_1.output}" - } - }, - "DepthMap_1": { - "nodeType": "DepthMap", - "position": [ - 1800, - 0 - ], - "inputs": { - "input": "{PrepareDenseScene_1.input}", - "imagesFolder": "{PrepareDenseScene_1.output}" - } - }, - "FeatureExtraction_1": { - "nodeType": "FeatureExtraction", - "position": [ - 200, - 0 - ], - "inputs": { - "input": "{CameraInit_1.output}" - } - }, - "FeatureMatching_1": { - "nodeType": "FeatureMatching", - "position": [ - 600, - 0 - ], - "inputs": { - "input": "{ImageMatching_1.input}", - "featuresFolders": "{ImageMatching_1.featuresFolders}", - "imagePairsList": "{ImageMatching_1.output}", - "describerTypes": "{FeatureExtraction_1.describerTypes}" - } - }, - "ImageMatching_1": { - "nodeType": "ImageMatching", - "position": [ - 400, - 0 - ], - "inputs": { - "input": "{FeatureExtraction_1.input}", - "featuresFolders": [ - "{FeatureExtraction_1.output}" - ] - } - }, - "MeshFiltering_1": { - "nodeType": "MeshFiltering", - "position": [ - 2400, - 0 - ], - "inputs": { - "inputMesh": "{Meshing_1.outputMesh}" - } - }, - "Meshing_1": { - "nodeType": "Meshing", - "position": [ - 2200, - 0 - ], - "inputs": { - "input": "{DepthMapFilter_1.input}", - "depthMapsFolder": "{DepthMapFilter_1.output}" - } - }, - "PrepareDenseScene_1": { - "nodeType": "PrepareDenseScene", - "position": [ - 1600, - 0 - ], - "inputs": { - "input": "{SfMExpanding_1.output}" - } - }, - "Publish_1": { - "nodeType": "Publish", - "position": [ - 2800, - 0 - ], - "inputs": { - "inputFiles": [ - "{Texturing_1.outputMesh}", - "{Texturing_1.outputMaterial}", - "{Texturing_1.outputTextures}" - ] - } - }, - "RelativePoseEstimating_1": { - "nodeType": "RelativePoseEstimating", - "position": [ - 1000, - 0 - ], - "inputs": { - "input": "{TracksBuilding_1.input}", - "tracksFilename": "{TracksBuilding_1.output}", - "minInliers": 100 - } - }, - "SfMBootStraping_1": { - "nodeType": "SfMBootStraping", - "position": [ - 1200, - 0 - ], - "inputs": { - "input": "{RelativePoseEstimating_1.input}", - "tracksFilename": "{RelativePoseEstimating_1.tracksFilename}", - "pairs": "{RelativePoseEstimating_1.output}" - } - }, - "SfMExpanding_1": { - "nodeType": "SfMExpanding", - "position": [ - 1400, - 0 - ], - "inputs": { - "input": "{SfMBootStraping_1.output}", - "tracksFilename": "{SfMBootStraping_1.tracksFilename}", - "meshFilename": "{SfMBootStraping_1.meshFilename}" - } - }, - "Texturing_1": { - "nodeType": "Texturing", - "position": [ - 2600, - 0 - ], - "inputs": { - "input": "{Meshing_1.output}", - "imagesFolder": "{DepthMap_1.imagesFolder}", - "inputMesh": "{MeshFiltering_1.outputMesh}" - } - }, - "TracksBuilding_1": { - "nodeType": "TracksBuilding", - "position": [ - 800, - 0 - ], - "inputs": { - "input": "{FeatureMatching_1.input}", - "featuresFolders": "{FeatureMatching_1.featuresFolders}", - "matchesFolders": [ - "{FeatureMatching_1.output}" - ], - "describerTypes": "{FeatureMatching_1.describerTypes}" - } - } - } -} \ No newline at end of file diff --git a/meshroom/pipelines/photometricStereo.mg b/meshroom/pipelines/photometricStereo.mg deleted file mode 100644 index 07f5f8c37d..0000000000 --- a/meshroom/pipelines/photometricStereo.mg +++ /dev/null @@ -1,77 +0,0 @@ -{ - "header": { - "releaseVersion": "2025.1.0-develop", - "fileVersion": "2.0", - "template": true, - "nodesVersions": { - "CameraInit": "12.0", - "LightingCalibration": "1.0", - "PhotometricStereo": "1.0", - "Publish": "1.3", - "SphereDetection": "1.0" - } - }, - "graph": { - "CameraInit_1": { - "nodeType": "CameraInit", - "position": [ - 0, - 0 - ], - "inputs": {} - }, - "LightingCalibration_1": { - "nodeType": "LightingCalibration", - "position": [ - 400, - 0 - ], - "inputs": { - "inputPath": "{SphereDetection_1.input}", - "inputDetection": "{SphereDetection_1.output}" - } - }, - "PhotometricStereo_1": { - "nodeType": "PhotometricStereo", - "position": [ - 600, - 0 - ], - "inputs": { - "inputPath": "{LightingCalibration_1.inputPath}", - "pathToJSONLightFile": "{LightingCalibration_1.outputFile}" - } - }, - "Publish_1": { - "nodeType": "Publish", - "position": [ - 800, - 0 - ], - "inputs": { - "inputFiles": [ - "{PhotometricStereo_1.outputSfmDataNormal}", - "{PhotometricStereo_1.normals}", - "{PhotometricStereo_1.normalsWorld}", - "{PhotometricStereo_1.albedo}", - "{PhotometricStereo_1.outputSfmDataAlbedo}", - "{PhotometricStereo_1.inputPath}", - "{PhotometricStereo_1.outputSfmDataNormalPNG}", - "{PhotometricStereo_1.normalsPNG}", - "{PhotometricStereo_1.pathToJSONLightFile}" - ] - } - }, - "SphereDetection_1": { - "nodeType": "SphereDetection", - "position": [ - 200, - 0 - ], - "inputs": { - "input": "{CameraInit_1.output}", - "autoDetect": true - } - } - } -} From 95ebf83c18fb0b1f11b40e23a53d10ed2fbea93d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Candice=20Bent=C3=A9jac?= Date: Mon, 17 Mar 2025 12:36:05 +0100 Subject: [PATCH 2/9] [nodes] Add a "general" folder and move the ` Publish` node in it The `Publish` node will remain the only default node that comes with Meshroom. --- meshroom/nodes/{aliceVision => general}/Publish.py | 0 meshroom/nodes/general/__init__.py | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename meshroom/nodes/{aliceVision => general}/Publish.py (100%) create mode 100644 meshroom/nodes/general/__init__.py diff --git a/meshroom/nodes/aliceVision/Publish.py b/meshroom/nodes/general/Publish.py similarity index 100% rename from meshroom/nodes/aliceVision/Publish.py rename to meshroom/nodes/general/Publish.py diff --git a/meshroom/nodes/general/__init__.py b/meshroom/nodes/general/__init__.py new file mode 100644 index 0000000000..e69de29bb2 From cf29a6db742a099d3631e96b12b9b6b1aef878de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Candice=20Bent=C3=A9jac?= Date: Mon, 17 Mar 2025 12:37:30 +0100 Subject: [PATCH 3/9] [nodes] Remove the "aliceVision" and "blender" folders The nodes contained in these folders, except for the `Publish` node, are all moved to AliceVision's repository. --- .../nodes/aliceVision/ApplyCalibration.py | 49 -- .../nodes/aliceVision/CameraCalibration.py | 129 ---- meshroom/nodes/aliceVision/CameraInit.py | 686 ------------------ .../nodes/aliceVision/CameraLocalization.py | 202 ------ .../nodes/aliceVision/CameraRigCalibration.py | 161 ---- .../aliceVision/CameraRigLocalization.py | 167 ----- .../aliceVision/CheckerboardCalibration.py | 52 -- .../aliceVision/CheckerboardDetection.py | 75 -- .../aliceVision/ColorCheckerCorrection.py | 81 --- .../aliceVision/ColorCheckerDetection.py | 67 -- .../nodes/aliceVision/ConvertDistortion.py | 53 -- meshroom/nodes/aliceVision/ConvertMesh.py | 44 -- .../nodes/aliceVision/ConvertSfMFormat.py | 105 --- meshroom/nodes/aliceVision/DepthMap.py | 624 ---------------- meshroom/nodes/aliceVision/DepthMapFilter.py | 146 ---- .../nodes/aliceVision/DepthMapRendering.py | 60 -- .../aliceVision/DistortionCalibration.py | 64 -- .../nodes/aliceVision/ExportAnimatedCamera.py | 111 --- .../aliceVision/ExportColoredPointCloud.py | 37 - .../nodes/aliceVision/ExportDistortion.py | 99 --- meshroom/nodes/aliceVision/ExportImages.py | 83 --- meshroom/nodes/aliceVision/ExportMatches.py | 81 --- meshroom/nodes/aliceVision/ExportMaya.py | 222 ------ meshroom/nodes/aliceVision/ExportUSD.py | 46 -- meshroom/nodes/aliceVision/ExtractMetadata.py | 133 ---- .../nodes/aliceVision/FeatureExtraction.py | 165 ----- meshroom/nodes/aliceVision/FeatureMatching.py | 210 ------ .../nodes/aliceVision/FeatureRepeatability.py | 120 --- .../aliceVision/GlobalRotationEstimating.py | 66 -- meshroom/nodes/aliceVision/GlobalSfM.py | 111 --- meshroom/nodes/aliceVision/ImageMasking.py | 136 ---- meshroom/nodes/aliceVision/ImageMatching.py | 140 ---- .../aliceVision/ImageMatchingMultiSfM.py | 152 ---- meshroom/nodes/aliceVision/ImageProcessing.py | 628 ---------------- .../nodes/aliceVision/ImageSegmentation.py | 94 --- meshroom/nodes/aliceVision/ImportE57.py | 65 -- .../nodes/aliceVision/ImportKnownPoses.py | 44 -- .../aliceVision/IntrinsicsTransforming.py | 67 -- .../nodes/aliceVision/KeyframeSelection.py | 409 ----------- .../nodes/aliceVision/LdrToHdrCalibration.py | 254 ------- meshroom/nodes/aliceVision/LdrToHdrMerge.py | 336 --------- .../nodes/aliceVision/LdrToHdrSampling.py | 284 -------- meshroom/nodes/aliceVision/LidarDecimating.py | 57 -- meshroom/nodes/aliceVision/LidarMerging.py | 40 - meshroom/nodes/aliceVision/LidarMeshing.py | 137 ---- .../nodes/aliceVision/LightingCalibration.py | 73 -- .../nodes/aliceVision/LightingEstimation.py | 82 --- meshroom/nodes/aliceVision/MaskProcessing.py | 85 --- meshroom/nodes/aliceVision/MergeMeshes.py | 69 -- meshroom/nodes/aliceVision/MeshDecimate.py | 77 -- meshroom/nodes/aliceVision/MeshDenoising.py | 92 --- meshroom/nodes/aliceVision/MeshFiltering.py | 117 --- meshroom/nodes/aliceVision/MeshMasking.py | 103 --- .../aliceVision/MeshRemoveUnseenFaces.py | 69 -- meshroom/nodes/aliceVision/MeshResampling.py | 82 --- meshroom/nodes/aliceVision/Meshing.py | 483 ------------ meshroom/nodes/aliceVision/NodalSfM.py | 51 -- .../nodes/aliceVision/NormalIntegration.py | 52 -- .../nodes/aliceVision/NormalMapRendering.py | 52 -- .../nodes/aliceVision/PanoramaCompositing.py | 118 --- .../nodes/aliceVision/PanoramaEstimation.py | 181 ----- meshroom/nodes/aliceVision/PanoramaInit.py | 160 ---- meshroom/nodes/aliceVision/PanoramaMerging.py | 77 -- .../aliceVision/PanoramaPostProcessing.py | 126 ---- .../aliceVision/PanoramaPrepareImages.py | 41 -- meshroom/nodes/aliceVision/PanoramaSeams.py | 70 -- meshroom/nodes/aliceVision/PanoramaWarping.py | 98 --- .../nodes/aliceVision/PhotometricStereo.py | 140 ---- .../nodes/aliceVision/PrepareDenseScene.py | 108 --- .../aliceVision/RelativePoseEstimating.py | 69 -- .../nodes/aliceVision/SelectConnectedViews.py | 64 -- meshroom/nodes/aliceVision/SfMAlignment.py | 118 --- meshroom/nodes/aliceVision/SfMChecking.py | 77 -- meshroom/nodes/aliceVision/SfMColorizing.py | 41 -- meshroom/nodes/aliceVision/SfMDistances.py | 63 -- meshroom/nodes/aliceVision/SfMFilter.py | 57 -- meshroom/nodes/aliceVision/SfMMerge.py | 103 --- .../nodes/aliceVision/SfMPoseInjecting.py | 55 -- .../aliceVision/SfMSplitReconstructed.py | 47 -- .../nodes/aliceVision/SfMSurveyInjecting.py | 47 -- meshroom/nodes/aliceVision/SfMToRig.py | 40 - meshroom/nodes/aliceVision/SfMTransfer.py | 110 --- meshroom/nodes/aliceVision/SfMTransform.py | 266 ------- .../nodes/aliceVision/SfMTriangulation.py | 154 ---- meshroom/nodes/aliceVision/SfmBootstraping.py | 84 --- meshroom/nodes/aliceVision/SfmExpanding.py | 181 ----- meshroom/nodes/aliceVision/SketchfabUpload.py | 275 ------- meshroom/nodes/aliceVision/SphereDetection.py | 89 --- meshroom/nodes/aliceVision/Split360Images.py | 139 ---- .../nodes/aliceVision/StructureFromMotion.py | 393 ---------- meshroom/nodes/aliceVision/Texturing.py | 371 ---------- meshroom/nodes/aliceVision/TracksBuilding.py | 97 --- meshroom/nodes/aliceVision/__init__.py | 0 meshroom/nodes/blender/ScenePreview.py | 141 ---- meshroom/nodes/blender/__init__.py | 0 meshroom/nodes/blender/scripts/__init__.py | 0 meshroom/nodes/blender/scripts/preview.py | 434 ----------- 97 files changed, 13213 deletions(-) delete mode 100644 meshroom/nodes/aliceVision/ApplyCalibration.py delete mode 100644 meshroom/nodes/aliceVision/CameraCalibration.py delete mode 100644 meshroom/nodes/aliceVision/CameraInit.py delete mode 100644 meshroom/nodes/aliceVision/CameraLocalization.py delete mode 100644 meshroom/nodes/aliceVision/CameraRigCalibration.py delete mode 100644 meshroom/nodes/aliceVision/CameraRigLocalization.py delete mode 100644 meshroom/nodes/aliceVision/CheckerboardCalibration.py delete mode 100644 meshroom/nodes/aliceVision/CheckerboardDetection.py delete mode 100644 meshroom/nodes/aliceVision/ColorCheckerCorrection.py delete mode 100644 meshroom/nodes/aliceVision/ColorCheckerDetection.py delete mode 100644 meshroom/nodes/aliceVision/ConvertDistortion.py delete mode 100644 meshroom/nodes/aliceVision/ConvertMesh.py delete mode 100644 meshroom/nodes/aliceVision/ConvertSfMFormat.py delete mode 100644 meshroom/nodes/aliceVision/DepthMap.py delete mode 100644 meshroom/nodes/aliceVision/DepthMapFilter.py delete mode 100644 meshroom/nodes/aliceVision/DepthMapRendering.py delete mode 100644 meshroom/nodes/aliceVision/DistortionCalibration.py delete mode 100644 meshroom/nodes/aliceVision/ExportAnimatedCamera.py delete mode 100644 meshroom/nodes/aliceVision/ExportColoredPointCloud.py delete mode 100644 meshroom/nodes/aliceVision/ExportDistortion.py delete mode 100644 meshroom/nodes/aliceVision/ExportImages.py delete mode 100644 meshroom/nodes/aliceVision/ExportMatches.py delete mode 100644 meshroom/nodes/aliceVision/ExportMaya.py delete mode 100644 meshroom/nodes/aliceVision/ExportUSD.py delete mode 100644 meshroom/nodes/aliceVision/ExtractMetadata.py delete mode 100644 meshroom/nodes/aliceVision/FeatureExtraction.py delete mode 100644 meshroom/nodes/aliceVision/FeatureMatching.py delete mode 100644 meshroom/nodes/aliceVision/FeatureRepeatability.py delete mode 100644 meshroom/nodes/aliceVision/GlobalRotationEstimating.py delete mode 100644 meshroom/nodes/aliceVision/GlobalSfM.py delete mode 100644 meshroom/nodes/aliceVision/ImageMasking.py delete mode 100644 meshroom/nodes/aliceVision/ImageMatching.py delete mode 100644 meshroom/nodes/aliceVision/ImageMatchingMultiSfM.py delete mode 100644 meshroom/nodes/aliceVision/ImageProcessing.py delete mode 100644 meshroom/nodes/aliceVision/ImageSegmentation.py delete mode 100644 meshroom/nodes/aliceVision/ImportE57.py delete mode 100644 meshroom/nodes/aliceVision/ImportKnownPoses.py delete mode 100644 meshroom/nodes/aliceVision/IntrinsicsTransforming.py delete mode 100644 meshroom/nodes/aliceVision/KeyframeSelection.py delete mode 100644 meshroom/nodes/aliceVision/LdrToHdrCalibration.py delete mode 100644 meshroom/nodes/aliceVision/LdrToHdrMerge.py delete mode 100644 meshroom/nodes/aliceVision/LdrToHdrSampling.py delete mode 100644 meshroom/nodes/aliceVision/LidarDecimating.py delete mode 100644 meshroom/nodes/aliceVision/LidarMerging.py delete mode 100644 meshroom/nodes/aliceVision/LidarMeshing.py delete mode 100644 meshroom/nodes/aliceVision/LightingCalibration.py delete mode 100644 meshroom/nodes/aliceVision/LightingEstimation.py delete mode 100644 meshroom/nodes/aliceVision/MaskProcessing.py delete mode 100644 meshroom/nodes/aliceVision/MergeMeshes.py delete mode 100644 meshroom/nodes/aliceVision/MeshDecimate.py delete mode 100644 meshroom/nodes/aliceVision/MeshDenoising.py delete mode 100644 meshroom/nodes/aliceVision/MeshFiltering.py delete mode 100644 meshroom/nodes/aliceVision/MeshMasking.py delete mode 100644 meshroom/nodes/aliceVision/MeshRemoveUnseenFaces.py delete mode 100644 meshroom/nodes/aliceVision/MeshResampling.py delete mode 100644 meshroom/nodes/aliceVision/Meshing.py delete mode 100644 meshroom/nodes/aliceVision/NodalSfM.py delete mode 100644 meshroom/nodes/aliceVision/NormalIntegration.py delete mode 100644 meshroom/nodes/aliceVision/NormalMapRendering.py delete mode 100644 meshroom/nodes/aliceVision/PanoramaCompositing.py delete mode 100644 meshroom/nodes/aliceVision/PanoramaEstimation.py delete mode 100644 meshroom/nodes/aliceVision/PanoramaInit.py delete mode 100644 meshroom/nodes/aliceVision/PanoramaMerging.py delete mode 100644 meshroom/nodes/aliceVision/PanoramaPostProcessing.py delete mode 100644 meshroom/nodes/aliceVision/PanoramaPrepareImages.py delete mode 100644 meshroom/nodes/aliceVision/PanoramaSeams.py delete mode 100644 meshroom/nodes/aliceVision/PanoramaWarping.py delete mode 100644 meshroom/nodes/aliceVision/PhotometricStereo.py delete mode 100644 meshroom/nodes/aliceVision/PrepareDenseScene.py delete mode 100644 meshroom/nodes/aliceVision/RelativePoseEstimating.py delete mode 100644 meshroom/nodes/aliceVision/SelectConnectedViews.py delete mode 100644 meshroom/nodes/aliceVision/SfMAlignment.py delete mode 100644 meshroom/nodes/aliceVision/SfMChecking.py delete mode 100644 meshroom/nodes/aliceVision/SfMColorizing.py delete mode 100644 meshroom/nodes/aliceVision/SfMDistances.py delete mode 100644 meshroom/nodes/aliceVision/SfMFilter.py delete mode 100644 meshroom/nodes/aliceVision/SfMMerge.py delete mode 100644 meshroom/nodes/aliceVision/SfMPoseInjecting.py delete mode 100644 meshroom/nodes/aliceVision/SfMSplitReconstructed.py delete mode 100644 meshroom/nodes/aliceVision/SfMSurveyInjecting.py delete mode 100644 meshroom/nodes/aliceVision/SfMToRig.py delete mode 100644 meshroom/nodes/aliceVision/SfMTransfer.py delete mode 100644 meshroom/nodes/aliceVision/SfMTransform.py delete mode 100644 meshroom/nodes/aliceVision/SfMTriangulation.py delete mode 100644 meshroom/nodes/aliceVision/SfmBootstraping.py delete mode 100644 meshroom/nodes/aliceVision/SfmExpanding.py delete mode 100644 meshroom/nodes/aliceVision/SketchfabUpload.py delete mode 100644 meshroom/nodes/aliceVision/SphereDetection.py delete mode 100644 meshroom/nodes/aliceVision/Split360Images.py delete mode 100644 meshroom/nodes/aliceVision/StructureFromMotion.py delete mode 100644 meshroom/nodes/aliceVision/Texturing.py delete mode 100644 meshroom/nodes/aliceVision/TracksBuilding.py delete mode 100644 meshroom/nodes/aliceVision/__init__.py delete mode 100644 meshroom/nodes/blender/ScenePreview.py delete mode 100644 meshroom/nodes/blender/__init__.py delete mode 100644 meshroom/nodes/blender/scripts/__init__.py delete mode 100644 meshroom/nodes/blender/scripts/preview.py diff --git a/meshroom/nodes/aliceVision/ApplyCalibration.py b/meshroom/nodes/aliceVision/ApplyCalibration.py deleted file mode 100644 index a90c98100c..0000000000 --- a/meshroom/nodes/aliceVision/ApplyCalibration.py +++ /dev/null @@ -1,49 +0,0 @@ -__version__ = "1.0" - -from meshroom.core import desc -from meshroom.core.utils import VERBOSE_LEVEL - - -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="SfMData", - description="Input SfMData file.", - value="", - ), - desc.File( - name="calibration", - label="Calibration", - description="Calibration file (SfmData or Lens calibration file).", - value="", - ), - desc.BoolParam( - name="useJson", - label="Use Lens Calibration File", - description="Calibration is a Lens calibration file generated using 3Dequalizer instead of an sfmData.", - value=False, - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="output", - label="SMData", - description="Path to the output SfMData file.", - value="{nodeCacheFolder}/sfmData.sfm", - ), - ] diff --git a/meshroom/nodes/aliceVision/CameraCalibration.py b/meshroom/nodes/aliceVision/CameraCalibration.py deleted file mode 100644 index 3cbb637b43..0000000000 --- a/meshroom/nodes/aliceVision/CameraCalibration.py +++ /dev/null @@ -1,129 +0,0 @@ -__version__ = "1.0" - -from meshroom.core import desc -from meshroom.core.utils import VERBOSE_LEVEL - - -class CameraCalibration(desc.AVCommandLineNode): - commandLine = 'aliceVision_cameraCalibration {allParams}' - - category = 'Utils' - documentation = ''' - ''' - - inputs = [ - desc.File( - name="input", - label="Input", - description="Input images in one of the following form:\n" - " - folder containing images.\n" - " - image sequence like \"/path/to/seq.@.jpg\".\n" - " - video file.", - value="", - ), - desc.ChoiceParam( - name="pattern", - label="Pattern", - description="Type of pattern (CHESSBOARD, CIRCLES, ASYMMETRIC_CIRCLES, ASYMMETRIC_CCTAG).", - value="CHESSBOARD", - values=["CHESSBOARD", "CIRCLES", "ASYMMETRIC_CIRCLES", "ASYMMETRIC_CCTAG"], - ), - desc.GroupAttribute( - name="size", - label="Size", - description="Number of inner corners per one of board dimension like W H.", - groupDesc=[ - desc.IntParam( - name="width", - label="Width", - description="", - value=7, - range=(0, 10000, 1), - ), - desc.IntParam( - name="height", - label="Height", - description="", - value=5, - range=(0, 10000, 1), - ), - ], - ), - desc.FloatParam( - name="squareSize", - label="Square Size", - description="Size of the grid's square cells (mm).", - value=1.0, - range=(0.0, 100.0, 1.0), - ), - desc.IntParam( - name="nbDistortionCoef", - label="Nb Distortion Coef", - description="Number of distortion coefficients.", - value=3, - range=(0, 5, 1), - ), - desc.IntParam( - name="maxFrames", - label="Max Frames", - description="Maximum number of frames to extract from the video file.", - value=0, - range=(0, 5, 1), - ), - desc.IntParam( - name="maxCalibFrames", - label="Max Calib Frames", - description="Maximum number of frames to use to calibrate from the selected frames.", - value=100, - range=(0, 1000, 1), - ), - desc.IntParam( - name="calibGridSize", - label="Calib Grid Size", - description="Define the number of cells per edge.", - value=10, - range=(0, 50, 1), - ), - desc.IntParam( - name="minInputFrames", - label="Min Input Frames", - description="Minimum number of frames to limit the refinement loop.", - value=10, - range=(0, 100, 1), - ), - desc.FloatParam( - name="maxTotalAvgErr", - label="Max Total Avg Err", - description="Maximum total average error.", - value=0.10000000000000001, - range=(0.0, 1.0, 0.01), - ), - desc.File( - name="debugRejectedImgFolder", - label="Debug Rejected Img Folder", - description="Folder to export images that were deleted during the refinement loop.", - value="", - ), - desc.File( - name="debugSelectedImgFolder", - label="Debug Selected Img Folder", - description="Folder to export debug images.", - value="", - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="output", - label="Output", - description="Output filename for intrinsic [and extrinsic] parameters.", - value="{nodeCacheFolder}/cameraCalibration.cal", - ), - ] diff --git a/meshroom/nodes/aliceVision/CameraInit.py b/meshroom/nodes/aliceVision/CameraInit.py deleted file mode 100644 index 0ea928d9ec..0000000000 --- a/meshroom/nodes/aliceVision/CameraInit.py +++ /dev/null @@ -1,686 +0,0 @@ -__version__ = "12.0" - -import os -import json -import psutil -import shutil -import tempfile -import logging - -from meshroom.core import desc, Version -from meshroom.core.utils import RAW_COLOR_INTERPRETATION, VERBOSE_LEVEL -from meshroom.multiview import FilesByType, findFilesByTypeInFolder - -Viewpoint = [ - desc.IntParam( - name="viewId", - label="ID", - description="Image UID.", - value=-1, - range=None, - ), - desc.IntParam( - name="poseId", - label="Pose ID", - description="Pose ID.", - value=-1, - range=None, - ), - desc.File( - name="path", - label="Image Path", - description="Image filepath.", - value="", - ), - desc.IntParam( - name="intrinsicId", - label="Intrinsic", - description="Internal camera parameters.", - value=-1, - range=None, - ), - desc.IntParam( - name="rigId", - label="Rig", - description="Rig parameters.", - value=-1, - range=None, - ), - desc.IntParam( - name="subPoseId", - label="Rig Sub-Pose", - description="Rig sub-pose parameters.", - value=-1, - range=None, - ), - desc.StringParam( - name="metadata", - label="Image Metadata", - description="The configuration of the Viewpoints is based on the images' metadata.\n" - "The important ones are:\n" - " - Focal Length: the focal length in mm.\n" - " - Make and Model: this information allows to convert the focal in mm into a focal length in " - "pixels using an embedded sensor database.\n" - " - Serial Number: allows to uniquely identify a device so multiple devices with the same Make, " - "Model can be differentiated and their internal parameters are optimized separately.", - value="", - invalidate=False, - advanced=True, - ), -] - -Intrinsic = [ - desc.IntParam( - name="intrinsicId", - label="ID", - description="Intrinsic UID.", - value=-1, - range=None, - ), - desc.FloatParam( - name="initialFocalLength", - label="Initial Focal Length", - description="Initial guess on the focal length (in mm).\n" - "When we have an initial value from EXIF, this value is not accurate but it cannot be wrong.\n" - "So this value is used to limit the range of possible values in the optimization.\n" - "If this value is set to -1, it will not be used and the focal length will not be bounded.", - value=-1.0, - range=None, - ), - desc.FloatParam( - name="focalLength", - label="Focal Length", - description="Known/calibrated focal length (in mm).", - value=1000.0, - range=(0.0, 10000.0, 1.0), - ), - desc.FloatParam( - name="pixelRatio", - label="Pixel Ratio", - description="Ratio between the pixel width and the pixel height.", - value=1.0, - range=(0.0, 10.0, 0.1), - ), - desc.BoolParam( - name="pixelRatioLocked", - label="Pixel Ratio Locked", - description="The pixel ratio value is locked for estimation.", - value=True, - ), - desc.BoolParam( - name="scaleLocked", - label="Focal length Locked", - description="The focal length is locked for estimation.", - value=False, - ), - desc.BoolParam( - name="offsetLocked", - label="Optical Center Locked", - description="The optical center coordinates are locked for estimation.", - value=False, - ), - desc.BoolParam( - name="distortionLocked", - label="Distortion Locked", - description="The distortion parameters are locked for estimation.", - value=False, - ), - desc.ChoiceParam( - name="type", - label="Camera Type", - description="Mathematical model used to represent a camera:\n" - " - pinhole: Simplest projective camera model without optical distortion " - "(focal and optical center).\n" - " - equidistant: Non-projective camera model suited for full-fisheye optics.\n" - " - equirectangular: Projection model used in panoramas.\n", - value="pinhole", - values=["pinhole", "equidistant", "equirectangular"], - ), - desc.ChoiceParam( - name="distortionType", - label="Distortion Type", - description="Mathematical model used to represent the distortion:\n" - " - radialk1: radial distortion with one parameter.\n" - " - radialk3: radial distortion with three parameters (Best for pinhole cameras).\n" - " - radialk3pt: radial distortion with three parameters and normalized with the sum of parameters " - "(Best for equidistant cameras).\n" - " - brown: distortion with 3 radial and 2 tangential parameters.\n" - " - fisheye1: distortion with 1 parameter suited for fisheye optics (like 120deg FoV).\n" - " - fisheye4: distortion with 4 parameters suited for fisheye optics (like 120deg FoV).\n", - value="radialk3", - values=["none", "radialk1", "radialk3", "radialk3pt", "brown", "fisheye4", "fisheye1"], - ), - desc.IntParam( - name="width", - label="Width", - description="Image width.", - value=0, - range=(0, 10000, 1), - ), - desc.IntParam( - name="height", - label="Height", - description="Image height.", - value=0, - range=(0, 10000, 1), - ), - desc.FloatParam( - name="sensorWidth", - label="Sensor Width", - description="Sensor width (in mm).", - value=36.0, - range=(0.0, 1000.0, 1.0), - ), - desc.FloatParam( - name="sensorHeight", - label="Sensor Height", - description="Sensor height (in mm).", - value=24.0, - range=(0.0, 1000.0, 1.0), - ), - desc.StringParam( - name="serialNumber", - label="Serial Number", - description="Device serial number (Camera UID and Lens UID combined).", - value="", - ), - desc.GroupAttribute( - name="principalPoint", - label="Principal Point", - description="Position of the optical center in the image (i.e. the sensor surface).", - groupDesc=[ - desc.FloatParam( - name="x", - label="x", - description="", - value=0.0, - range=(0.0, 10000.0, 1.0), - ), - desc.FloatParam( - name="y", - label="y", - description="", - value=0.0, - range=(0.0, 10000.0, 1.0), - ), - ], - ), - desc.ChoiceParam( - name="initializationMode", - label="Initialization Mode", - description="Defines how this intrinsic was initialized:\n" - " - calibrated: calibrated externally.\n" - " - estimated: estimated from metadata and/or sensor width.\n" - " - unknown: unknown camera parameters (can still have default value guess).\n" - " - none: not set.", - values=["calibrated", "estimated", "unknown", "none"], - value="none", - ), - desc.ChoiceParam( - name="distortionInitializationMode", - label="Distortion Initialization Mode", - description="Defines how the distortion model and parameters were initialized:\n" - " - calibrated: calibrated externally.\n" - " - estimated: estimated from a database of generic calibration.\n" - " - unknown: unknown camera parameters (can still have default value guess).\n" - " - none: not set.", - values=["calibrated", "estimated", "unknown", "none"], - value="none", - ), - desc.ListAttribute( - name="distortionParams", - elementDesc=desc.FloatParam( - name="p", - label="", - description="", - value=0.0, - range=(-0.1, 0.1, 0.01), - ), - label="Distortion Params", - description="Distortion parameters.", - ), - desc.GroupAttribute( - name="undistortionOffset", - label="Undistortion Offset", - description="Undistortion offset.", - groupDesc=[ - desc.FloatParam( - name="x", - label="x", - description="", - value=0.0, - range=(0.0, 10000.0, 1.0), - ), - desc.FloatParam( - name="y", - label="y", - description="", - value=0.0, - range=(0.0, 10000.0, 1.0), - ), - ], - ), - desc.ListAttribute( - name="undistortionParams", - elementDesc=desc.FloatParam( - name="p", - label="", - description="", - value=0.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 speed-up the reconstruction.", - value=False, - ), -] - - -def readSfMData(sfmFile): - """ Read views and intrinsics from a .sfm file - - Args: - sfmFile: the .sfm file containing views and intrinsics - - Returns: - The views and intrinsics of the .sfm as two separate lists - """ - # skip decoding errors to avoid potential exceptions due to non utf-8 characters in images metadata - with open(sfmFile, 'r', encoding='utf-8', errors='ignore') as f: - data = json.load(f) - - intrinsicsKeys = [i.name for i in Intrinsic] - - intrinsics = [{k: v for k, v in item.items() if k in intrinsicsKeys} for item in data.get("intrinsics", [])] - for intrinsic in intrinsics: - pp = intrinsic.get('principalPoint', (0, 0)) - intrinsic['principalPoint'] = {} - intrinsic['principalPoint']['x'] = pp[0] - intrinsic['principalPoint']['y'] = pp[1] - - # convert empty string distortionParams (i.e: Pinhole model) to empty list - distortionParams = intrinsic.get('distortionParams', '') - if distortionParams == '': - intrinsic['distortionParams'] = list() - - offset = intrinsic.get('undistortionOffset', (0, 0)) - intrinsic['undistortionOffset'] = {} - intrinsic['undistortionOffset']['x'] = offset[0] - intrinsic['undistortionOffset']['y'] = offset[1] - - undistortionParams = intrinsic.get('undistortionParams', '') - if 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: - view['metadata'] = json.dumps(view['metadata']) # convert metadata to string - - return views, intrinsics - - -class CameraInit(desc.AVCommandLineNode, desc.InitNode): - commandLine = "aliceVision_cameraInit {allParams} --allowSingleView 1" # don't throw an error if there is only one image - - size = desc.DynamicNodeSize("viewpoints") - - category = "Sparse Reconstruction" - documentation = """ -This node describes your dataset. It lists the Viewpoints candidates, the guess about the type of optic, the initial -focal length and which images are sharing the same internal camera parameters, as well as potential camera rigs. - -When you import new images into Meshroom, this node is automatically configured from the analysis of the images' metadata. -The software can support images without any metadata but it is recommended to have them for robustness. - -### Metadata -Metadata allow images to be grouped together and provide an initialization of the focal length (in pixel unit). -The needed metadata are: - * **Focal Length**: the focal length in mm. - * **Make** & **Model**: this information allows to convert the focal in mm into a focal length in pixels using an - embedded sensor database. - * **Serial Number**: allows to uniquely identify a device so multiple devices with the same Make, Model can be - differentiated and their internal parameters are optimized separately (in the photogrammetry case). -""" - - inputs = [ - desc.ListAttribute( - name="viewpoints", - elementDesc=desc.GroupAttribute( - name="viewpoint", - label="Viewpoint", - description="Viewpoint.", - groupDesc=Viewpoint, - ), - label="Viewpoints", - description="Input viewpoints.", - group="", - ), - desc.ListAttribute( - name="intrinsics", - elementDesc=desc.GroupAttribute( - name="intrinsic", - label="Intrinsic", - description="Intrinsic.", - groupDesc=Intrinsic, - ), - label="Intrinsics", - description="Camera intrinsics.", - group="", - ), - desc.File( - name="sensorDatabase", - label="Sensor Database", - description="Camera sensor with database path.", - value="${ALICEVISION_SENSOR_DB}", - invalidate=False, - ), - desc.File( - name="lensCorrectionProfileInfo", - label="LCP Info", - description="Lens Correction Profile filepath or database directory.", - value="${ALICEVISION_LENS_PROFILE_INFO}", - invalidate=False, - ), - desc.BoolParam( - name="lensCorrectionProfileSearchIgnoreCameraModel", - label="LCP Generic Search", - description="The lens name and camera maker are used to match the LCP database, but the camera model is ignored.", - value=True, - advanced=True, - ), - desc.FloatParam( - name="defaultFieldOfView", - label="Default Field Of View", - description="Default value for the field of view (in degrees) used as an initialization value when there is " - "no focal or field of view in the image metadata.", - value=45.0, - range=(0.0, 180.0, 1.0), - invalidate=False, - ), - desc.ChoiceParam( - name="groupCameraFallback", - label="Group Camera Fallback", - description="If there is no serial number in the images' metadata, devices cannot be accurately identified.\n" - "Therefore, internal camera parameters cannot be shared among images reliably.\n" - "A fallback grouping strategy must be chosen:\n" - " - global: group images from comparable devices (same make/model/focal) globally.\n" - " - folder: group images from comparable devices only within the same folder.\n" - " - image: never group images from comparable devices.", - values=["global", "folder", "image"], - value="folder", - invalidate=False, - ), - desc.ChoiceParam( - name="rawColorInterpretation", - label="RAW Color Interpretation", - description="Allows to choose how RAW data are color processed:\n" - " - None: Debayering without any color processing.\n" - " - LibRawNoWhiteBalancing: Simple neutralization.\n" - " - LibRawWhiteBalancing: Use internal white balancing from libraw.\n" - " - DCPLinearProcessing: Use DCP color profile.\n" - " - DCPMetadata: Same as None with DCP info added in metadata.", - values=RAW_COLOR_INTERPRETATION, - value="DCPLinearProcessing" if os.environ.get("ALICEVISION_COLOR_PROFILE_DB", "") else "LibRawWhiteBalancing", - ), - desc.File( - name="colorProfileDatabase", - label="Color Profile Database", - description="Color Profile database directory path.", - value="${ALICEVISION_COLOR_PROFILE_DB}", - enabled=lambda node: node.rawColorInterpretation.value.startswith("DCP"), - invalidate=False, - ), - desc.BoolParam( - name="errorOnMissingColorProfile", - label="Error On Missing DCP Color Profile", - description="When enabled, if no color profile is found for at least one image, then an error is thrown.\n" - "When disabled, if no color profile is found for some images, it will fallback to " - "libRawWhiteBalancing for those images.", - value=True, - enabled=lambda node: node.rawColorInterpretation.value.startswith("DCP"), - ), - desc.ChoiceParam( - name="viewIdMethod", - label="ViewId Method", - description="Allows to choose the way the viewID is generated:\n" - " - metadata : Generate viewId from image metadata.\n" - " - filename : Generate viewId from filename using regex.", - value="metadata", - values=["metadata", "filename"], - invalidate=False, - advanced=True, - ), - desc.StringParam( - name="viewIdRegex", - label="ViewId Regex", - description="Regex used to catch number used as viewId in filename." - "You should capture specific parts of the filename with parentheses to define matching elements." - " (only numbers will work)\n" - "Some examples of patterns:\n" - " - Match the longest number at the end of the filename (default value): " - r'".*?(\d+)"' + "\n" + - " - Match the first number found in filename: " - r'"(\d+).*"', - value=r".*?(\d+)", - invalidate=False, - advanced=True, - enabled=lambda node: node.viewIdMethod.value == "filename", - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="output", - label="SfMData", - description="Output SfMData.", - value="{nodeCacheFolder}/cameraInit.sfm", - ), - ] - - def __init__(self): - super(CameraInit, self).__init__() - - def initialize(self, node, inputs, recursiveInputs): - # Reset graph inputs - self.resetAttributes(node, ["viewpoints", "intrinsics"]) - - filesByType = FilesByType() - searchedForImages = False - - if recursiveInputs: - filesByType.extend(findFilesByTypeInFolder(recursiveInputs, recursive=True)) - searchedForImages = True - - # Add views and intrinsics from a file if it was provided, or look for the images - if len(inputs) == 1 and os.path.isfile(inputs[0]) and os.path.splitext(inputs[0])[-1] in ('.json', '.sfm'): - views, intrinsics = readSfMData(inputs[0]) - self.extendAttributes(node, {"viewpoints": views, "intrinsics": intrinsics}) - else: - filesByType.extend(findFilesByTypeInFolder(inputs, recursive=False)) - searchedForImages = True - - # If there was no input file, check that the directories do contain images - if searchedForImages and not filesByType.images: - raise ValueError("No valid input file or no image in the provided directories") - - views, intrinsics = self.buildIntrinsics(node, filesByType.images) - self.setAttributes(node, {"viewpoints": views, "intrinsics": intrinsics}) - - def upgradeTypes(self, intrinsic, itype): - if itype == "pinhole": - intrinsic['type'] = "pinhole" - intrinsic['distortionType'] = "none" - intrinsic['undistortionType'] = "none" - - elif itype == "radial1": - intrinsic['type'] = "pinhole" - intrinsic['distortionType'] = "radialk1" - intrinsic['undistortionType'] = "none" - - elif itype == "radial3": - intrinsic['type'] = "pinhole" - intrinsic['distortionType'] = "radialk3" - intrinsic['undistortionType'] = "none" - - elif itype == "brown": - intrinsic['type'] = "pinhole" - intrinsic['distortionType'] = "brown" - intrinsic['undistortionType'] = "none" - - elif itype == "fisheye4": - intrinsic['type'] = "pinhole" - intrinsic['distortionType'] = "fisheye4" - intrinsic['undistortionType'] = "none" - - elif itype == "fisheye1": - intrinsic['type'] = "pinhole" - intrinsic['distortionType'] = "fisheye1" - intrinsic['undistortionType'] = "none" - - elif itype == "equidistant": - intrinsic['type'] = "equidistant" - intrinsic['distortionType'] = "none" - intrinsic['undistortionType'] = "none" - - elif itype == "equidistant_r3": - intrinsic['type'] = "equidistant" - intrinsic['distortionType'] = "radialk3pt" - intrinsic['undistortionType'] = "none" - - else: - intrinsic['type'] = "pinhole" - intrinsic['distortionType'] = "none" - intrinsic['undistortionType'] = "none" - - def upgradeAttributeValues(self, attrValues, fromVersion): - - # Starting with version 6, the principal point is now relative to the image center - if fromVersion < Version(6, 0): - for intrinsic in attrValues['intrinsics']: - principalPoint = intrinsic['principalPoint'] - intrinsic['principalPoint'] = { - "x": int(principalPoint["x"] - 0.5 * intrinsic['width']), - "y": int(principalPoint["y"] - 0.5 * intrinsic['height']) - } - - # Starting with version 7, the focal length is now in mm - if fromVersion < Version(7, 0): - for intrinsic in attrValues['intrinsics']: - pxInitialFocalLength = intrinsic['pxInitialFocalLength'] - pxFocalLength = intrinsic['pxFocalLength'] - sensorWidth = intrinsic['sensorWidth'] - width = intrinsic['width'] - focalLength = (pxFocalLength / width) * sensorWidth - initialFocalLength = (pxInitialFocalLength / width) * sensorWidth - intrinsic['initialFocalLength'] = initialFocalLength - intrinsic['focalLength'] = focalLength - intrinsic['pixelRatio'] = 1.0 - intrinsic['pixelRatioLocked'] = False - - # Upgrade types - if fromVersion < Version(10, 0): - for intrinsic in attrValues['intrinsics']: - itype = intrinsic['type'] - self.upgradeTypes(intrinsic, itype) - - return attrValues - - def readSfMData(self, sfmFile): - return readSfMData(sfmFile) - - def buildIntrinsics(self, node, additionalViews=()): - """ Build intrinsics from node current views and optional additional views - - Args: - node: the CameraInit node instance to build intrinsics for - additionalViews: (optional) the new views (list of path to images) to add to the node's viewpoints - - Returns: - The updated views and intrinsics as two separate lists - """ - assert isinstance(node.nodeDesc, CameraInit) - if node.graph: - # make a copy of the node outside the graph - # to change its cache folder without modifying the original node - node = node.graph.copyNode(node)[0] - - tmpCache = tempfile.mkdtemp() - node.updateInternals(tmpCache) - - try: - os.makedirs(os.path.join(tmpCache, node.internalFolder)) - self.createViewpointsFile(node, additionalViews) - cmd = self.buildCommandLine(node.chunks[0]) - logging.debug(' - commandLine: {}'.format(cmd)) - proc = psutil.Popen(cmd, stdout=None, stderr=None, shell=True) - stdout, stderr = proc.communicate() - # proc.wait() - if proc.returncode != 0: - raise RuntimeError('CameraInit failed with error code {}.\nCommand was: "{}".\n'.format( - proc.returncode, cmd) - ) - - # Reload result of aliceVision_cameraInit - cameraInitSfM = node.output.value - return readSfMData(cameraInitSfM) - - except Exception as e: - logging.debug("[CameraInit] Error while building intrinsics: {}".format(str(e))) - raise - finally: - if os.path.exists(tmpCache): - logging.debug("[CameraInit] Remove temp files in: {}".format(tmpCache)) - shutil.rmtree(tmpCache) - - def createViewpointsFile(self, node, additionalViews=()): - node.viewpointsFile = "" - if node.viewpoints or additionalViews: - newViews = [] - for path in additionalViews: # format additional views to match json format - newViews.append({"path": path}) - 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']] - intrinsic['undistortionType'] = 'none' - views = node.viewpoints.getPrimitiveValue(exportDefault=False) - - # convert the metadata string into a map - for view in views: - if 'metadata' in view: - view['metadata'] = json.loads(view['metadata']) - - sfmData = { - "version": [1, 2, 12], - "views": views + newViews, - "intrinsics": intrinsics, - "featureFolder": "", - "matchingFolder": "", - } - node.viewpointsFile = os.path.join(node.internalFolder, 'viewpoints.sfm').format(**node._cmdVars) - with open(node.viewpointsFile, 'w') as f: - json.dump(sfmData, f, indent=4) - - def buildCommandLine(self, chunk): - cmd = desc.CommandLineNode.buildCommandLine(self, chunk) - if chunk.node.viewpointsFile: - cmd += ' --input "{}"'.format(chunk.node.viewpointsFile) - return cmd - - def processChunk(self, chunk): - self.createViewpointsFile(chunk.node) - desc.CommandLineNode.processChunk(self, chunk) diff --git a/meshroom/nodes/aliceVision/CameraLocalization.py b/meshroom/nodes/aliceVision/CameraLocalization.py deleted file mode 100644 index a778fda9c5..0000000000 --- a/meshroom/nodes/aliceVision/CameraLocalization.py +++ /dev/null @@ -1,202 +0,0 @@ -__version__ = "1.0" - -from meshroom.core import desc -from meshroom.core.utils import DESCRIBER_TYPES, VERBOSE_LEVEL - - -class CameraLocalization(desc.AVCommandLineNode): - commandLine = 'aliceVision_cameraLocalization {allParams}' - - category = 'Utils' - documentation = ''' - ''' - - inputs = [ - desc.File( - name="sfmdata", - label="SfMData", - description="The SfMData file generated by AliceVision.", - value="", - ), - desc.File( - name="mediafile", - label="Media File", - description="The folder path or the filename for the media to track.", - value="", - ), - desc.File( - name="visualDebug", - label="Visual Debug Folder", - description="If a folder is provided, this enables visual debug and all the debugging information will be saved in that folder.", - value="", - ), - desc.File( - name="descriptorPath", - label="Descriptor Path", - description="Folder containing the descriptors for all the images (ie. the *.desc.).", - value="", - ), - desc.ChoiceParam( - name="matchDescTypes", - label="Match Desc Types", - description="Describer types to use for the matching.", - values=DESCRIBER_TYPES, - value=["dspsift"], - exclusive=False, - joinChar=",", - ), - desc.ChoiceParam( - name="preset", - label="Preset", - description="Preset for the feature extractor when localizing a new image (low, medium, normal, high, ultra).", - value="normal", - values=["low", "medium", "normal", "high", "ultra"], - ), - desc.ChoiceParam( - name="resectionEstimator", - label="Resection Estimator", - description="The type of *sac framework to use for resection (acransac, loransac).", - value="acransac", - values=["acransac", "loransac"], - ), - desc.ChoiceParam( - name="matchingEstimator", - label="Matching Estimator", - description="The type of *sac framework to use for matching (acransac, loransac).", - value="acransac", - values=["acransac", "loransac"], - ), - desc.File( - name="calibration", - label="Calibration", - description="Calibration file.", - value="", - ), - desc.BoolParam( - name="refineIntrinsics", - label="Refine Intrinsics", - description="Enable/Disable camera intrinsics refinement for each localized image.", - value=False, - ), - desc.FloatParam( - name="reprojectionError", - label="Reprojection Error", - description="Maximum reprojection error (in pixels) allowed for resectioning. If set to 0, it lets the ACRansac select an optimal value.", - value=4.0, - range=(0.1, 50.0, 0.1), - ), - desc.IntParam( - name="nbImageMatch", - label="Nb Image Match", - description="[voctree] Number of images to retrieve in database.", - value=4, - range=(1, 1000, 1), - ), - desc.IntParam( - name="maxResults", - label="Max Results", - description="[voctree] For algorithm AllResults, it stops the image matching when this number of matched images is reached. If 0 it is ignored.", - value=10, - range=(1, 100, 1), - ), - desc.IntParam( - name="commonviews", - label="Common Views", - description="[voctree] Number of minimum images in which a point must be seen to be used in cluster tracking.", - value=3, - range=(2, 50, 1), - ), - desc.File( - name="voctree", - label="Voctree", - description="[voctree] Filename for the vocabulary tree.", - value="${ALICEVISION_VOCTREE}", - ), - desc.File( - name="voctreeWeights", - label="Voctree Weights", - description="[voctree] Filename for the vocabulary tree weights.", - value="", - ), - desc.ChoiceParam( - name="algorithm", - label="Algorithm", - description="[voctree] Algorithm type: FirstBest, AllResults.", - value="AllResults", - values=["FirstBest", "AllResults"], - ), - desc.FloatParam( - name="matchingError", - label="Matching Error", - description="[voctree] Maximum matching error (in pixels) allowed for image matching with geometric verification. If set to 0, it lets the ACRansac select an optimal value.", - value=4.0, - range=(0.0, 50.0, 1.0), - ), - desc.IntParam( - name="nbFrameBufferMatching", - label="Nb Frame Buffer Matching", - description="[voctree] Number of previous frames of the sequence to use for matching (0 = Disable).", - value=10, - range=(0, 100, 1), - ), - desc.BoolParam( - name="robustMatching", - label="Robust Matching", - description="[voctree] Enable/Disable the robust matching between query and database images, all putative matches will be considered.", - value=True, - ), - desc.IntParam( - name="nNearestKeyFrames", - label="N Nearest Key Frames", - description="[cctag] Number of images to retrieve in the database. Parameters specific for final (optional) bundle adjustment optimization of the sequence.", - value=5, - range=(1, 100, 1), - ), - desc.StringParam( - name="globalBundle", - label="Global Bundle", - description="[bundle adjustment] If --refineIntrinsics is not set, this option allows to run a final global bundle adjustment to refine the scene.", - value="", - ), - desc.BoolParam( - name="noDistortion", - label="No Distortion", - description="[bundle adjustment] It does not take into account distortion during the BA, it considers the distortion coefficients to all be equal to 0.", - value=False, - ), - desc.BoolParam( - name="noBArefineIntrinsics", - label="No BA Refine Intrinsics", - description="[bundle adjustment] If set to true, does not refine intrinsics during BA.", - value=False, - ), - desc.IntParam( - name="minPointVisibility", - label="Min Point Visibility", - description="[bundle adjustment] Minimum number of observations that a point must have in order to be considered for bundle adjustment.", - value=2, - range=(2, 50, 1), - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="outputAlembic", - label="Alembic", - description="Filename for the SfMData export file (where camera poses will be stored).", - value="{nodeCacheFolder}/trackedCameras.abc", - ), - desc.File( - name="outputJSON", - label="JSON File", - description="Filename for the localization results as .json.", - value="{nodeCacheFolder}/trackedCameras.json", - ), - ] diff --git a/meshroom/nodes/aliceVision/CameraRigCalibration.py b/meshroom/nodes/aliceVision/CameraRigCalibration.py deleted file mode 100644 index f788134280..0000000000 --- a/meshroom/nodes/aliceVision/CameraRigCalibration.py +++ /dev/null @@ -1,161 +0,0 @@ -__version__ = "1.0" - -from meshroom.core import desc -from meshroom.core.utils import DESCRIBER_TYPES, VERBOSE_LEVEL - - -class CameraRigCalibration(desc.AVCommandLineNode): - commandLine = 'aliceVision_rigCalibration {allParams}' - - category = 'Utils' - documentation = ''' - ''' - - inputs = [ - desc.File( - name="sfmdata", - label="SfMData", - description="Input SfMData file.", - value="", - ), - desc.File( - name="mediapath", - label="Media Path", - description="The path to the video file, the folder of the image sequence or a text file\n" - "(one image path per line) for each camera of the rig (eg. --mediapath /path/to/cam1.mov /path/to/cam2.mov).", - value="", - ), - desc.File( - name="cameraIntrinsics", - label="Camera Intrinsics", - description="The intrinsics calibration file for each camera of the rig (eg. --cameraIntrinsics /path/to/calib1.txt /path/to/calib2.txt).", - value="", - ), - desc.File( - name="export", - label="Export File", - description="Filename for the alembic file containing the rig poses with the 3D points. It also saves a file for each camera named 'filename.cam##.abc'.", - value="trackedcameras.abc", - ), - desc.File( - name="descriptorPath", - label="Descriptor Path", - description="Folder containing the .desc.", - value="", - ), - desc.ChoiceParam( - name="matchDescTypes", - label="Match Describer Types", - description="The describer types to use for the matching.", - values=DESCRIBER_TYPES, - value=["dspsift"], - exclusive=False, - joinChar=",", - ), - desc.ChoiceParam( - name="preset", - label="Preset", - description="Preset for the feature extractor when localizing a new image (low, medium, normal, high, ultra).", - value="normal", - values=["low", "medium", "normal", "high", "ultra"], - ), - desc.ChoiceParam( - name="resectionEstimator", - label="Resection Estimator", - description="The type of *sac framework to use for resection (acransac, loransac).", - value="acransac", - values=["acransac", "loransac"], - ), - desc.ChoiceParam( - name="matchingEstimator", - label="Matching Estimator", - description="The type of *sac framework to use for matching (acransac, loransac).", - value="acransac", - values=["acransac", "loransac"], - ), - desc.StringParam( - name="refineIntrinsics", - label="Refine Intrinsics", - description="Enable/Disable camera intrinsics refinement for each localized image.", - value="", - ), - desc.FloatParam( - name="reprojectionError", - label="Reprojection Error", - description="Maximum reprojection error (in pixels) allowed for resectioning.\n" - "If set to 0, it lets the ACRansac select an optimal value.", - value=4.0, - range=(0.0, 10.0, 0.1), - ), - desc.IntParam( - name="maxInputFrames", - label="Max Input Frames", - description="Maximum number of frames to read in input. 0 means no limit.", - value=0, - range=(0, 1000, 1), - ), - desc.File( - name="voctree", - label="Voctree", - description="[voctree] Filename for the vocabulary tree.", - value="${ALICEVISION_VOCTREE}", - ), - desc.File( - name="voctreeWeights", - label="Voctree Weights", - description="[voctree] Filename for the vocabulary tree weights.", - value="", - ), - desc.ChoiceParam( - name="algorithm", - label="Algorithm", - description="[voctree] Algorithm type: {FirstBest, AllResults}.", - value="AllResults", - values=["FirstBest", "AllResults"], - ), - desc.IntParam( - name="nbImageMatch", - label="Nb Image Match", - description="[voctree] Number of images to retrieve in the database.", - value=4, - range=(0, 50, 1), - ), - desc.IntParam( - name="maxResults", - label="Max Results", - description="[voctree] For algorithm AllResults, it stops the image matching when this number of matched images is reached. If set to 0, it is ignored.", - value=10, - range=(0, 100, 1), - ), - desc.FloatParam( - name="matchingError", - label="Matching Error", - description="[voctree] Maximum matching error (in pixels) allowed for image matching with geometric verification.\n" - "If set to 0, it lets the ACRansac select an optimal value.", - value=4.0, - range=(0.0, 10.0, 0.1), - ), - desc.IntParam( - name="nNearestKeyFrames", - label="N Nearest Key Frames", - description="[cctag] Number of images to retrieve in database.", - value=5, - range=(0, 50, 1), - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="outfile", - label="Output File", - description="The name of the file to store the calibration data in.", - value="{nodeCacheFolder}/cameraRigCalibration.rigCal", - ), - ] diff --git a/meshroom/nodes/aliceVision/CameraRigLocalization.py b/meshroom/nodes/aliceVision/CameraRigLocalization.py deleted file mode 100644 index 331c171052..0000000000 --- a/meshroom/nodes/aliceVision/CameraRigLocalization.py +++ /dev/null @@ -1,167 +0,0 @@ -__version__ = "1.0" - -from meshroom.core import desc -from meshroom.core.utils import DESCRIBER_TYPES, VERBOSE_LEVEL - - -class CameraRigLocalization(desc.AVCommandLineNode): - commandLine = 'aliceVision_rigLocalization {allParams}' - - category = 'Utils' - documentation = ''' - ''' - - inputs = [ - desc.File( - name="sfmdata", - label="SfMData", - description="The input SfMData file.", - value="", - ), - desc.File( - name="mediapath", - label="Media Path", - description="The path to the video file, the folder of the image sequence or a text file (one image path per line) for each camera of the rig (eg. --mediapath /path/to/cam1.mov /path/to/cam2.mov).", - value="", - ), - desc.File( - name="calibration", - label="Rig Calibration File", - description="The file containing the calibration data for the rig (subposes).", - value="", - ), - desc.File( - name="cameraIntrinsics", - label="Camera Intrinsics", - description="The intrinsics calibration file for each camera of the rig (eg. --cameraIntrinsics /path/to/calib1.txt /path/to/calib2.txt).", - value="", - ), - desc.File( - name="descriptorPath", - label="Descriptor Path", - description="Folder containing the .desc.", - value="", - ), - desc.ChoiceParam( - name="matchDescTypes", - label="Match Describer Types", - description="The describer types to use for the matching.", - values=DESCRIBER_TYPES, - value=["dspsift"], - exclusive=False, - joinChar=",", - ), - desc.ChoiceParam( - name="preset", - label="Preset", - description="Preset for the feature extractor when localizing a new image (low, medium, normal, high, ultra).", - value="normal", - values=["low", "medium", "normal", "high", "ultra"], - ), - desc.ChoiceParam( - name="resectionEstimator", - label="Resection Estimator", - description="The type of *sac framework to use for resection (acransac, loransac).", - value="acransac", - values=["acransac", "loransac"], - ), - desc.ChoiceParam( - name="matchingEstimator", - label="Matching Estimator", - description="The type of *sac framework to use for matching (acransac, loransac).", - value="acransac", - values=["acransac", "loransac"], - ), - desc.StringParam( - name="refineIntrinsics", - label="Refine Intrinsics", - description="Enable/Disable camera intrinsics refinement for each localized image.", - value="", - ), - desc.FloatParam( - name="reprojectionError", - label="Reprojection Error", - description="Maximum reprojection error (in pixels) allowed for resectioning.\n" - "If set to 0, it lets the ACRansac select an optimal value.", - value=4.0, - range=(0.0, 10.0, 0.1), - ), - desc.BoolParam( - name="useLocalizeRigNaive", - label="Use Localize Rig Naive", - description="Enable/Disable the naive method for rig localization: naive method tries to localize each camera separately.", - value=False, - ), - desc.FloatParam( - name="angularThreshold", - label="Angular Threshold", - description="The maximum angular threshold in degrees between feature bearing vector and 3D point direction. Used only with the opengv method.", - value=0.1, - range=(0.0, 10.0, 0.01), - ), - desc.File( - name="voctree", - label="Voctree", - description="[voctree] Filename for the vocabulary tree.""", - value="${ALICEVISION_VOCTREE}", - ), - desc.File( - name="voctreeWeights", - label="Voctree Weights", - description="[voctree] Filename for the vocabulary tree weights.", - value="", - ), - desc.ChoiceParam( - name="algorithm", - label="Algorithm", - description="[voctree] Algorithm type: {FirstBest, AllResults}.", - value="AllResults", - values=["FirstBest", "AllResults"], - ), - desc.IntParam( - name="nbImageMatch", - label="Nb Image Match", - description="[voctree] Number of images to retrieve in the database.", - value=4, - range=(0, 100, 1), - ), - desc.IntParam( - name="maxResults", - label="Max Results", - description="[voctree] For algorithm AllResults, it stops the image matching when this number of matched images is reached.\n" - "If set to 0, it is ignored.", - value=10, - range=(0, 100, 1), - ), - desc.FloatParam( - name="matchingError", - label="Matching Error", - description="[voctree] Maximum matching error (in pixels) allowed for image matching with geometric verification.\n" - "If set to 0, it lets the ACRansac select an optimal value.", - value=4.0, - range=(0.0, 10.0, 0.1), - ), - desc.IntParam( - name="nNearestKeyFrames", - label="N Nearest Key Frames", - description="[cctag] Number of images to retrieve in database.", - value=5, - range=(0, 50, 1), - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="outputAlembic", - label="Alembic", - description="Filename for the SfMData export file (where camera poses will be stored).", - value="{nodeCacheFolder}/trackedcameras.abc", - ), - ] diff --git a/meshroom/nodes/aliceVision/CheckerboardCalibration.py b/meshroom/nodes/aliceVision/CheckerboardCalibration.py deleted file mode 100644 index 1cdc8229bd..0000000000 --- a/meshroom/nodes/aliceVision/CheckerboardCalibration.py +++ /dev/null @@ -1,52 +0,0 @@ -__version__ = '1.0' - -from meshroom.core import desc -from meshroom.core.utils import VERBOSE_LEVEL - - -class CheckerboardCalibration(desc.AVCommandLineNode): - commandLine = 'aliceVision_checkerboardCalibration {allParams}' - size = desc.DynamicNodeSize('input') - - category = 'Other' - documentation = ''' -Estimate the camera intrinsics and extrinsincs on a set of checkerboard images. -''' - - inputs = [ - desc.File( - name="input", - label="Input SfMData", - description="SfMData file.", - value="", - ), - desc.File( - name="checkerboards", - label="Checkerboards Folder", - description="Folder containing checkerboard JSON files.", - value="", - ), - desc.FloatParam( - name="squareSize", - label="Square Size", - description="Checkerboard square width in mm", - value=10., - range=(0.1, 100., 0.1), - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="output", - label="SfMData File", - description="Path to the output SfMData file.", - value="{nodeCacheFolder}/sfmData.sfm", - ) - ] diff --git a/meshroom/nodes/aliceVision/CheckerboardDetection.py b/meshroom/nodes/aliceVision/CheckerboardDetection.py deleted file mode 100644 index 6d48ba31a5..0000000000 --- a/meshroom/nodes/aliceVision/CheckerboardDetection.py +++ /dev/null @@ -1,75 +0,0 @@ -__version__ = "1.0" - -from meshroom.core import desc -from meshroom.core.utils import VERBOSE_LEVEL - - -class CheckerboardDetection(desc.AVCommandLineNode): - commandLine = 'aliceVision_checkerboardDetection {allParams}' - size = desc.DynamicNodeSize('input') - parallelization = desc.Parallelization(blockSize=5) - commandLineRange = '--rangeStart {rangeStart} --rangeSize {rangeBlockSize}' - - category = 'Other' - documentation = ''' -Detect checkerboard structures in a set of images. -The detection method also supports nested calibration grids. -''' - - inputs = [ - desc.File( - name="input", - label="Input", - description="Input SfMData file. Viewpoints must correspond to lens calibration grids.", - value="", - ), - desc.BoolParam( - name="useNestedGrids", - label="Nested Calibration Grid", - description="Enable if images contain nested calibration grids. These grids must be centered on the image center.", - value=False, - ), - desc.BoolParam( - name="doubleSize", - label="Double Size", - description="Double the image size prior to processing.", - value=False, - ), - desc.BoolParam( - name="ignorePixelAspectRatio", - label="Ignore Pixel Aspect Ratio", - description="Ignore pixel aspect ratio for detection.", - value=False, - ), - desc.BoolParam( - name="exportDebugImages", - label="Export Debug Images", - description="Export debug images.", - value=False, - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="output", - label="Folder", - description="Output folder.", - value="{nodeCacheFolder}", - ), - desc.File( - name="checkerLines", - enabled=lambda node: node.exportDebugImages.value, - label="Checker Lines", - description="Debug images.", - semantic="image", - value="{nodeCacheFolder}/.png", - group="", # do not export on the command line - ), - ] diff --git a/meshroom/nodes/aliceVision/ColorCheckerCorrection.py b/meshroom/nodes/aliceVision/ColorCheckerCorrection.py deleted file mode 100644 index 007ec4bb5c..0000000000 --- a/meshroom/nodes/aliceVision/ColorCheckerCorrection.py +++ /dev/null @@ -1,81 +0,0 @@ -__version__ = "1.0" - -from meshroom.core import desc -from meshroom.core.utils import EXR_STORAGE_DATA_TYPE, VERBOSE_LEVEL - -import os.path - - -class ColorCheckerCorrection(desc.AVCommandLineNode): - commandLine = 'aliceVision_colorCheckerCorrection {allParams}' - size = desc.DynamicNodeSize('input') - # parallelization = desc.Parallelization(blockSize=40) - # commandLineRange = '--rangeStart {rangeStart} --rangeSize {rangeBlockSize}' - - documentation = ''' -(BETA) \\ -Performs color calibration from Macbeth color checker chart. - -The node assumes all the images to process are sharing the same colorimetric properties. -All the input images will get the same correction. - -If multiple color charts are submitted, only the first one will be taken in account. -''' - - inputs = [ - desc.File( - name="inputData", - label="Color Checker Data", - description="Position and colorimetric data of the color checker.", - value="", - ), - desc.File( - name="input", - label="Input", - description="Input SfMData file, image filenames or regex(es) on the image file path.\n" - "Supported regex: '#' matches a single digit, '@' one or more digits, '?' one character and " - "'*' zero or more.", - value="", - ), - desc.ChoiceParam( - name="extension", - label="Output File Extension", - description="Output image file extension.", - value="exr", - values=["exr", ""], - ), - desc.ChoiceParam( - name="storageDataType", - label="EXR Storage Data Type", - description="Storage data type for EXR output:\n" - " - float: Use full floating point (32 bits per channel).\n" - " - half: Use half float (16 bits per channel).\n" - " - halfFinite: Use half float, but clamp values to avoid non-finite values.\n" - " - auto: Use half float if all values can fit, else use full float.", - values=EXR_STORAGE_DATA_TYPE, - value="float", - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="outSfMData", - label="SfMData", - description="Output SfMData.", - value=lambda attr: ("{nodeCacheFolder}/" + os.path.basename(attr.node.input.value)) if (os.path.splitext(attr.node.input.value)[1] in [".abc", ".sfm"]) else "", - group="", # do not export on the command line - ), - desc.File( - name="output", - label="Folder", - description="Output images folder.", - value="{nodeCacheFolder}", - ), - ] diff --git a/meshroom/nodes/aliceVision/ColorCheckerDetection.py b/meshroom/nodes/aliceVision/ColorCheckerDetection.py deleted file mode 100644 index ae8286615c..0000000000 --- a/meshroom/nodes/aliceVision/ColorCheckerDetection.py +++ /dev/null @@ -1,67 +0,0 @@ -__version__ = "1.0" - -from meshroom.core import desc -from meshroom.core.utils import VERBOSE_LEVEL - - -class ColorCheckerDetection(desc.AVCommandLineNode): - commandLine = 'aliceVision_colorCheckerDetection {allParams}' - size = desc.DynamicNodeSize('input') - # parallelization = desc.Parallelization(blockSize=40) - # commandLineRange = '--rangeStart {rangeStart} --rangeSize {rangeBlockSize}' - - documentation = ''' -(BETA) \\ -Performs Macbeth color checker chart detection. - -Outputs: -- the detected color charts position and colors -- the associated transform matrix from "theoric" to "measured" -assuming that the "theoric" Macbeth chart corners coordinates are: -(0, 0), (1675, 0), (1675, 1125), (0, 1125) - -Dev notes: -- Fisheye/pinhole is not handled -- ColorCheckerViewer is unstable with multiple color chart within a same image -''' - - inputs = [ - desc.File( - name="input", - label="Input", - description="SfMData file input, image filenames or regex(es) on the image file path.\n" - "Supported regex: '#' matches a single digit, '@' one or more digits, '?' one character " - "and '*' zero or more.", - value="", - ), - desc.IntParam( - name="maxCount", - label="Max Count By Image", - description="Maximum color charts count to detect in a single image.", - value=1, - range=(1, 3, 1), - advanced=True, - ), - desc.BoolParam( - name="debug", - label="Debug", - description="If checked, debug data will be generated.", - value=False, - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="outputData", - label="Color Checker Data", - description="Output position and colorimetric data extracted from detected color checkers in the images.", - value="{nodeCacheFolder}/ccheckers.json", - ), - ] diff --git a/meshroom/nodes/aliceVision/ConvertDistortion.py b/meshroom/nodes/aliceVision/ConvertDistortion.py deleted file mode 100644 index 19094c05b8..0000000000 --- a/meshroom/nodes/aliceVision/ConvertDistortion.py +++ /dev/null @@ -1,53 +0,0 @@ -__version__ = "1.0" - -from meshroom.core import desc -from meshroom.core.utils import VERBOSE_LEVEL - - -class ConvertDistortion(desc.AVCommandLineNode): - commandLine = 'aliceVision_convertDistortion {allParams}' - size = desc.DynamicNodeSize('input') - - category = 'Utils' - documentation = ''' - Convert distortions between different models. - ''' - - inputs = [ - desc.File( - name="input", - label="Input", - description="Input SfMData file.", - value="", - ), - desc.ChoiceParam( - name="from", - label="From", - description="Distortion model to convert from.", - value="distortion", - values=["distortion", "undistortion"], - ), - desc.ChoiceParam( - name="to", - label="To", - description="Distortion model to convert to.", - value="undistortion", - values=["distortion", "undistortion"], - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="output", - label="Output", - description="Path to the output SfMData file.", - value="{nodeCacheFolder}/sfm.abc", - ), - ] diff --git a/meshroom/nodes/aliceVision/ConvertMesh.py b/meshroom/nodes/aliceVision/ConvertMesh.py deleted file mode 100644 index 27b3d64c1c..0000000000 --- a/meshroom/nodes/aliceVision/ConvertMesh.py +++ /dev/null @@ -1,44 +0,0 @@ -__version__ = "1.0" - -from meshroom.core import desc -from meshroom.core.utils import VERBOSE_LEVEL - - -class ConvertMesh(desc.AVCommandLineNode): - commandLine = 'aliceVision_convertMesh {allParams}' - - category = 'Utils' - documentation = '''This node allows to convert a mesh to another format.''' - - inputs = [ - desc.File( - name="inputMesh", - label="Input Mesh", - description="Input mesh (*.obj, *.mesh, *.meshb, *.ply, *.off, *.stl).", - value="", - ), - desc.ChoiceParam( - name="outputMeshFileType", - label="Output File Type", - description="Output mesh format (*.obj, *.gltf, *.fbx, *.stl).", - value="obj", - values=["gltf", "obj", "fbx", "stl"], - group="", - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="output", - label="Mesh", - description="Output mesh (*.obj, *.mesh, *.meshb, *.ply, *.off, *.stl).", - value="{nodeCacheFolder}/mesh.{outputMeshFileTypeValue}", - ), - ] diff --git a/meshroom/nodes/aliceVision/ConvertSfMFormat.py b/meshroom/nodes/aliceVision/ConvertSfMFormat.py deleted file mode 100644 index 1b8d5a2aad..0000000000 --- a/meshroom/nodes/aliceVision/ConvertSfMFormat.py +++ /dev/null @@ -1,105 +0,0 @@ -__version__ = "2.0" - -from meshroom.core import desc -from meshroom.core.utils import DESCRIBER_TYPES, VERBOSE_LEVEL - - -class ConvertSfMFormat(desc.AVCommandLineNode): - commandLine = 'aliceVision_convertSfMFormat {allParams}' - size = desc.DynamicNodeSize('input') - - category = 'Utils' - documentation = ''' -Convert an SfM scene from one file format to another. -It can also be used to remove specific parts of from an SfM scene (like filter all 3D landmarks or filter 2D observations). -''' - - inputs = [ - desc.File( - name="input", - label="Input", - description="Input SfMData file.", - value="", - ), - desc.ChoiceParam( - name="fileExt", - label="SfM File Format", - description="Output SfM file format.", - value="abc", - values=["abc", "sfm", "json", "ply", "baf"], - group="", # exclude from command line - ), - desc.ChoiceParam( - name="describerTypes", - label="Describer Types", - description="Describer types to keep.", - values=DESCRIBER_TYPES, - value=["dspsift"], - exclusive=False, - joinChar=",", - exposed=True, - ), - desc.ListAttribute( - elementDesc=desc.File( - name="imageId", - label="Image ID", - description="UID or path of an image to add to the white list.", - value="", - ), - name="imageWhiteList", - label="Image White List", - description="Image white list (UIDs or image paths).", - ), - desc.BoolParam( - name="views", - label="Views", - description="Export views.", - value=True, - ), - desc.BoolParam( - name="intrinsics", - label="Intrinsics", - description="Export intrinsics.", - value=True, - ), - desc.BoolParam( - name="extrinsics", - label="Extrinsics", - description="Export extrinsics.", - value=True, - ), - desc.BoolParam( - name="structure", - label="Structure", - description="Export structure.", - value=True, - ), - desc.BoolParam( - name="observations", - label="Observations", - description="Export observations.", - value=True, - ), - desc.BoolParam( - name="surveys", - label="Surveys", - description="Export surveys.", - value=True, - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="output", - label="Output", - description="Path to the output SfMData file.", - value="{nodeCacheFolder}/sfm.{fileExtValue}", - ), - ] diff --git a/meshroom/nodes/aliceVision/DepthMap.py b/meshroom/nodes/aliceVision/DepthMap.py deleted file mode 100644 index bd391af037..0000000000 --- a/meshroom/nodes/aliceVision/DepthMap.py +++ /dev/null @@ -1,624 +0,0 @@ -__version__ = "5.0" - -from meshroom.core import desc -from meshroom.core.utils import VERBOSE_LEVEL - - -class DepthMap(desc.AVCommandLineNode): - commandLine = "aliceVision_depthMapEstimation {allParams}" - gpu = desc.Level.INTENSIVE - size = desc.DynamicNodeSize("input") - parallelization = desc.Parallelization(blockSize=12) - commandLineRange = "--rangeStart {rangeStart} --rangeSize {rangeBlockSize}" - - category = "Dense Reconstruction" - documentation = """ -Estimate a depth map for each calibrated camera using Plane Sweeping, a multi-view stereo algorithm notable for its -efficiency on modern graphics hardware (GPU). - -Adjust the downscale factor to compute depth maps at a higher/lower resolution. -Use a downscale factor of one (full-resolution) only if the quality of the input images is really high -(camera on a tripod with high-quality optics). - -## Online -[https://alicevision.org/#photogrammetry/depth_maps_estimation](https://alicevision.org/#photogrammetry/depth_maps_estimation) -""" - - inputs = [ - desc.File( - name="input", - label="SfMData", - description="Input SfMData file.", - value="", - ), - desc.File( - name="imagesFolder", - label="Images Folder", - description="Use images from a specific folder instead of those specified in the SfMData file.\n" - "Filename should be the image UID.", - value="", - ), - desc.ChoiceParam( - name="downscale", - label="Downscale", - description="Downscale the input images to compute the depth map.\n" - "Full resolution (downscale = 1) gives the best result,\n" - "but using a larger downscale will reduce computation time at the expense of quality.\n" - "If the images are noisy, blurry or if the surfaces are challenging (weakly-textured or with " - "specularities), a larger downscale may improve.", - value=2, - values=[1, 2, 4, 8, 16], - ), - desc.FloatParam( - name="minViewAngle", - label="Min View Angle", - description="Minimum angle between two views (select the neighbouring cameras, select depth planes from " - "epipolar segment point).", - value=2.0, - range=(0.0, 10.0, 0.1), - advanced=True, - ), - desc.FloatParam( - name="maxViewAngle", - label="Max View Angle", - description="Maximum angle between two views (select the neighbouring cameras, select depth planes from " - "epipolar segment point).", - value=70.0, - range=(10.0, 120.0, 1.0), - advanced=True, - ), - desc.GroupAttribute( - name="tiling", - label="Tiling", - description="Tiles are used to split the computation into fixed buffers to fit the GPU best.", - group=None, - groupDesc=[ - desc.IntParam( - name="tileBufferWidth", - label="Buffer Width", - description="Maximum tile buffer width.", - value=1024, - range=(-1, 2000, 10), - ), - desc.IntParam( - name="tileBufferHeight", - label="Buffer Height", - description="Maximum tile buffer height.", - value=1024, - range=(-1, 2000, 10), - ), - desc.IntParam( - name="tilePadding", - label="Padding", - description="Buffer padding for overlapping tiles.", - value=64, - range=(0, 500, 1), - ), - desc.BoolParam( - name="autoAdjustSmallImage", - label="Auto Adjust Small Image", - description="Automatically adjust depth map parameters if images are smaller than one tile\n" - "(maxTCamsPerTile = maxTCams, adjust step if needed).", - value=True, - advanced=True, - ), - ], - ), - desc.BoolParam( - name="chooseTCamsPerTile", - label="Choose Neighbour Cameras Per Tile", - description="Choose neighbour cameras per tile or globally to the image.", - value=True, - advanced=True, - ), - desc.IntParam( - name="maxTCams", - label="Max Nb Neighbour Cameras", - description="Maximum number of neighbour cameras per image.", - value=10, - range=(1, 20, 1), - ), - desc.GroupAttribute( - name="sgm", - label="SGM", - description="The Semi-Global Matching (SGM) step computes a similarity volume and extracts the initial " - "low-resolution depth map.\n" - "This method is highly robust but has limited depth precision (banding artifacts due to a " - "limited list of depth planes).", - group=None, - groupDesc=[ - desc.IntParam( - name="sgmScale", - label="Downscale Factor", - description="Downscale factor applied on source images for the SGM step (in addition to the global " - "downscale).", - value=2, - range=(-1, 10, 1), - ), - desc.IntParam( - name="sgmStepXY", - label="Step XY", - description="The step is used to compute the similarity volume for one pixel over N " - "(in the XY image plane).", - value=2, - range=(-1, 10, 1), - ), - desc.IntParam( - name="sgmStepZ", - label="Step Z", - description="Initial step used to compute the similarity volume on Z axis (every N pixels on the " - "epilolar line).\n" - "-1 means automatic estimation.\n" - "This value will be adjusted in all case to fit in the max memory (sgmMaxDepths).", - value=-1, - range=(-1, 10, 1), - ), - desc.IntParam( - name="sgmMaxTCamsPerTile", - label="Max Nb Neighbour Cameras Per Tile", - description="Maximum number of neighbour cameras used per tile.", - value=4, - range=(1, 20, 1), - ), - desc.IntParam( - name="sgmWSH", - label="WSH", - description="Half-size of the patch used to compute the similarity. Patch width is wsh*2+1.", - value=4, - range=(1, 20, 1), - advanced=True, - ), - desc.BoolParam( - name="sgmUseSfmSeeds", - label="Use SfM Landmarks", - description="Use landmarks from Structure-from-Motion as input seeds to define min/max depth ranges.", - value=True, - advanced=True, - ), - desc.FloatParam( - name="sgmSeedsRangeInflate", - label="Seeds Range Inflate", - description="Inflate factor to add margins around SfM seeds.", - value=0.2, - range=(0.0, 2.0, 0.1), - advanced=True, - ), - desc.FloatParam( - name="sgmDepthThicknessInflate", - label="Thickness Inflate", - description="Inflate factor to add margins to the depth thickness.", - value=0.0, - range=(0.0, 2.0, 0.1), - advanced=True, - ), - desc.FloatParam( - name="sgmMaxSimilarity", - label="Max Similarity", - description="Maximum similarity threshold (between 0 and 1) used to filter out poorly supported " - "depth values.", - value=1.0, - range=(0.0, 1.0, 0.01), - advanced=True, - ), - desc.FloatParam( - name="sgmGammaC", - label="GammaC", - description="GammaC threshold used for similarity computation.", - value=5.5, - range=(0.0, 30.0, 0.5), - advanced=True, - ), - desc.FloatParam( - name="sgmGammaP", - label="GammaP", - description="GammaP threshold used for similarity computation.", - value=8.0, - range=(0.0, 30.0, 0.5), - advanced=True, - ), - desc.FloatParam( - name="sgmP1", - label="P1", - description="P1 parameter for SGM filtering.", - value=10.0, - range=(0.0, 255.0, 0.5), - advanced=True, - ), - desc.FloatParam( - name="sgmP2Weighting", - label="P2 Weighting", - description="P2 weighting parameter for SGM filtering.", - value=100.0, - range=(-255.0, 255.0, 0.5), - advanced=True, - ), - desc.IntParam( - name="sgmMaxDepths", - label="Max Depths", - description="Maximum number of depths in the similarity volume.", - value=1500, - range=(1, 5000, 1), - advanced=True, - ), - desc.StringParam( - name="sgmFilteringAxes", - label="Filtering Axes", - description="Define axes for the filtering of the similarity volume.", - value="YX", - advanced=True, - ), - desc.BoolParam( - name="sgmDepthListPerTile", - label="Depth List Per Tile", - description="Select the list of depth planes per tile or globally to the image.", - value=True, - advanced=True, - ), - desc.BoolParam( - name="sgmUseConsistentScale", - label="Consistent Scale", - description="Compare patch with consistent scale for similarity volume computation.", - value=False, - ), - ], - ), - desc.GroupAttribute( - name="refine", - label="Refine", - description="The refine step computes a similarity volume in higher resolution but with a small depth " - "range around the SGM depth map.\n" - "This allows to compute a depth map with sub-pixel accuracy.", - group=None, - groupDesc=[ - desc.BoolParam( - name="refineEnabled", - label="Enable", - description="Enable depth/similarity map refinement process.", - value=True, - ), - desc.IntParam( - name="refineScale", - label="Downscale Factor", - description="Downscale factor applied on source images for the Refine step (in addition to the " - "global downscale).", - value=1, - range=(-1, 10, 1), - enabled=lambda node: node.refine.refineEnabled.value, - ), - desc.IntParam( - name="refineStepXY", - label="Step XY", - description="The step is used to compute the refine volume for one pixel over N (in the XY image plane).", - value=1, - range=(-1, 10, 1), - enabled=lambda node: node.refine.refineEnabled.value, - ), - desc.IntParam( - name="refineMaxTCamsPerTile", - label="Max Nb Neighbour Cameras Per Tile", - description="Maximum number of neighbour cameras used per tile.", - value=4, - range=(1, 20, 1), - enabled=lambda node: node.refine.refineEnabled.value, - ), - desc.IntParam( - name="refineSubsampling", - label="Number Of Subsamples", - description="The number of subsamples used to extract the best depth from the refine volume " - "(sliding gaussian window precision).", - value=10, - range=(1, 30, 1), - advanced=True, - enabled=lambda node: node.refine.refineEnabled.value, - ), - desc.IntParam( - name="refineHalfNbDepths", - label="Half Number Of Depths", - description="The thickness of the refine area around the initial depth map.\n" - "This parameter defines the number of depths in front of and behind the initial value\n" - "for which we evaluate the similarity with a finer z sampling.", - value=15, - range=(1, 50, 1), - advanced=True, - enabled=lambda node: node.refine.refineEnabled.value, - ), - desc.IntParam( - name="refineWSH", - label="WSH", - description="Half-size of the patch used to compute the similarity. Patch width is wsh*2+1.", - value=3, - range=(1, 20, 1), - advanced=True, - enabled=lambda node: node.refine.refineEnabled.value, - ), - desc.FloatParam( - name="refineSigma", - label="Sigma", - description="Sigma (2*sigma^2) of the Gaussian filter used to extract the best depth from " - "the refine volume.", - value=15.0, - range=(0.0, 30.0, 0.5), - advanced=True, - enabled=lambda node: node.refine.refineEnabled.value, - ), - desc.FloatParam( - name="refineGammaC", - label="GammaC", - description="GammaC threshold used for similarity computation.", - value=15.5, - range=(0.0, 30.0, 0.5), - advanced=True, - enabled=lambda node: node.refine.refineEnabled.value, - ), - desc.FloatParam( - name="refineGammaP", - label="GammaP", - description="GammaP threshold used for similarity computation.", - value=8.0, - range=(0.0, 30.0, 0.5), - advanced=True, - enabled=lambda node: node.refine.refineEnabled.value, - ), - desc.BoolParam( - name="refineInterpolateMiddleDepth", - label="Interpolate Middle Depth", - description="Enable middle depth bilinear interpolation.", - value=False, - enabled=lambda node: node.refine.refineEnabled.value, - ), - desc.BoolParam( - name="refineUseConsistentScale", - label="Consistent Scale", - description="Compare patch with consistent scale for similarity volume computation.", - value=False, - enabled=lambda node: node.refine.refineEnabled.value, - ), - ], - ), - desc.GroupAttribute( - name="colorOptimization", - label="Color Optimization", - description="Color optimization post-process parameters.", - group=None, - groupDesc=[ - desc.BoolParam( - name="colorOptimizationEnabled", - label="Enable", - description="Enable depth/similarity map post-process color optimization.", - value=True, - ), - desc.IntParam( - name="colorOptimizationNbIterations", - label="Number Of Iterations", - description="Number of iterations for the optimization.", - value=100, - range=(1, 500, 10), - advanced=True, - enabled=lambda node: node.colorOptimization.colorOptimizationEnabled.value, - ), - ], - ), - desc.GroupAttribute( - name="customPatchPattern", - label="Custom Patch Pattern", - description="User custom patch pattern for similarity comparison.", - advanced=True, - group=None, - groupDesc=[ - desc.BoolParam( - name="sgmUseCustomPatchPattern", - label="Enable For SGM", - description="Enable custom patch pattern for similarity volume computation at the SGM step.", - value=False, - advanced=True, - ), - desc.BoolParam( - name="refineUseCustomPatchPattern", - label="Enable For Refine", - description="Enable custom patch pattern for similarity volume computation at the Refine step.", - value=False, - advanced=True, - ), - desc.ListAttribute( - name="customPatchPatternSubparts", - label="Subparts", - description="User custom patch pattern subparts for similarity volume computation.", - advanced=True, - enabled=lambda node: (node.customPatchPattern.sgmUseCustomPatchPattern.value or - node.customPatchPattern.refineUseCustomPatchPattern.value), - elementDesc=desc.GroupAttribute( - name="customPatchPatternSubpart", - label="Patch Pattern Subpart", - description="Custom patch pattern subpart configuration for similarity volume computation.", - joinChar=":", - group=None, - groupDesc=[ - desc.ChoiceParam( - name="customPatchPatternSubpartType", - label="Type", - description="Patch pattern subpart type.", - value="full", - values=["full", "circle"], - ), - desc.FloatParam( - name="customPatchPatternSubpartRadius", - label="Radius / WSH", - description="Patch pattern subpart half-width or circle radius.", - value=2.5, - range=(0.5, 30.0, 0.1), - ), - desc.IntParam( - name="customPatchPatternSubpartNbCoords", - label="Coordinates", - description="Patch pattern subpart number of coordinates (for circle or ignore).", - value=12, - range=(3, 24, 1), - ), - desc.IntParam( - name="customPatchPatternSubpartLevel", - label="Level", - description="Patch pattern subpart image level.", - value=0, - range=(0, 2, 1), - ), - desc.FloatParam( - name="customPatchPatternSubpartWeight", - label="Weight", - description="Patch pattern subpart weight.", - value=1.0, - range=(0.0, 1.0, 0.1), - ), - ], - ), - ), - desc.BoolParam( - name="customPatchPatternGroupSubpartsPerLevel", - label="Group Subparts Per Level", - description="Group all subparts with the same image level.", - value=False, - advanced=True, - enabled=lambda node: (node.customPatchPattern.sgmUseCustomPatchPattern.value or - node.customPatchPattern.refineUseCustomPatchPattern.value), - ), - ], - ), - desc.GroupAttribute( - name="intermediateResults", - label="Intermediate Results", - description="Intermediate results parameters for debug purposes.\n" - "Warning: Dramatically affect performances and use large amount of storage.", - advanced=True, - group=None, - groupDesc=[ - desc.BoolParam( - name="exportIntermediateDepthSimMaps", - label="Export Depth Maps", - description="Export intermediate depth/similarity maps from the SGM and Refine steps.", - value=False, - advanced=True, - ), - desc.BoolParam( - name="exportIntermediateNormalMaps", - label="Export Normal Maps", - description="Export intermediate normal maps from the SGM and Refine steps.", - value=False, - advanced=True, - ), - desc.BoolParam( - name="exportIntermediateVolumes", - label="Export Volumes", - description="Export intermediate full similarity volumes from the SGM and Refine steps.", - value=False, - advanced=True, - ), - desc.BoolParam( - name="exportIntermediateCrossVolumes", - label="Export Cross Volumes", - description="Export intermediate similarity cross volumes from the SGM and Refine steps.", - value=False, - advanced=True, - ), - desc.BoolParam( - name="exportIntermediateTopographicCutVolumes", - label="Export Cut Volumes", - description="Export intermediate similarity topographic cut volumes from the SGM and Refine steps.", - value=False, - advanced=True, - ), - desc.BoolParam( - name="exportIntermediateVolume9pCsv", - label="Export 9 Points", - description="Export intermediate volumes 9 points from the SGM and Refine steps in CSV files.", - value=False, - advanced=True, - ), - desc.BoolParam( - name="exportTilePattern", - label="Export Tile Pattern", - description="Export the bounding boxes of tiles volumes as meshes. " - "This allows to visualize the depth map search areas.", - value=False, - advanced=True, - ), - ], - ), - desc.IntParam( - name="nbGPUs", - label="Number Of GPUs", - description="Number of GPUs to use (0 means that all the available GPUs will be used).", - value=0, - range=(0, 5, 1), - invalidate=False, - advanced=True, - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="output", - label="Folder", - description="Output folder for generated depth maps.", - value="{nodeCacheFolder}", - ), - # these attributes are only here to describe more accurately the output of the node - # by specifying that it generates 2 sequences of images - # (see in Viewer2D.qml how these attributes can be used) - desc.File( - name="depth", - label="Depth Maps", - description="Generated depth maps.", - semantic="image", - value="{nodeCacheFolder}/_depthMap.exr", - group="", # do not export on the command line - ), - desc.File( - name="sim", - label="Sim Maps", - description="Generated sim maps.", - semantic="image", - value="{nodeCacheFolder}/_simMap.exr", - group="", # do not export on the command line - ), - desc.File( - name="tilePattern", - label="Tile Pattern", - description="Debug: Tile pattern.", - value="{nodeCacheFolder}/_tilePattern.obj", - group="", # do not export on the command line - enabled=lambda node: node.intermediateResults.exportTilePattern.value, - ), - desc.File( - name="depthSgm", - label="Depth Maps SGM", - description="Debug: Depth maps SGM", - semantic="image", - value="{nodeCacheFolder}/_depthMap_sgm.exr", - group="", # do not export on the command line - enabled=lambda node: node.intermediateResults.exportIntermediateDepthSimMaps.value, - ), - desc.File( - name="depthSgmUpscaled", - label="Depth Maps SGM Upscaled", - description="Debug: Depth maps SGM upscaled.", - semantic="image", - value="{nodeCacheFolder}/_depthMap_sgmUpscaled.exr", - group="", # do not export on the command line - enabled=lambda node: node.intermediateResults.exportIntermediateDepthSimMaps.value, - ), - desc.File( - name="depthRefined", - label="Depth Maps Refined", - description="Debug: Depth maps after refinement", - semantic="image", - value="{nodeCacheFolder}/_depthMap_refinedFused.exr", - group="", # do not export on the command line - enabled=lambda node: node.intermediateResults.exportIntermediateDepthSimMaps.value, - ), - ] diff --git a/meshroom/nodes/aliceVision/DepthMapFilter.py b/meshroom/nodes/aliceVision/DepthMapFilter.py deleted file mode 100644 index 701708cf98..0000000000 --- a/meshroom/nodes/aliceVision/DepthMapFilter.py +++ /dev/null @@ -1,146 +0,0 @@ -__version__ = "4.0" - -from meshroom.core import desc -from meshroom.core.utils import VERBOSE_LEVEL - - -class DepthMapFilter(desc.AVCommandLineNode): - commandLine = 'aliceVision_depthMapFiltering {allParams}' - gpu = desc.Level.NORMAL - size = desc.DynamicNodeSize('input') - parallelization = desc.Parallelization(blockSize=24) - commandLineRange = '--rangeStart {rangeStart} --rangeSize {rangeBlockSize}' - - category = 'Dense Reconstruction' - documentation = ''' -Filter depth map values that are not coherent in multiple depth maps. -This allows to filter unstable points before starting the fusion of all depth maps in the Meshing node. -''' - - inputs = [ - desc.File( - name="input", - label="SfMData", - description="SfMData file.", - value="", - ), - desc.File( - name="depthMapsFolder", - label="Depth Maps Folder", - description="Input depth maps folder.", - value="", - ), - desc.FloatParam( - name="minViewAngle", - label="Min View Angle", - description="Minimum angle between two views.", - value=2.0, - range=(0.0, 10.0, 0.1), - advanced=True, - ), - desc.FloatParam( - name="maxViewAngle", - label="Max View Angle", - description="Maximum angle between two views.", - value=70.0, - range=(10.0, 120.0, 1.0), - advanced=True, - ), - desc.IntParam( - name="nNearestCams", - label="Number Of Nearest Cameras", - description="Number of nearest cameras used for filtering.", - value=10, - range=(0, 20, 1), - advanced=True, - ), - desc.IntParam( - name="minNumOfConsistentCams", - label="Min Consistent Cameras", - description="Minimum number of consistent cameras.", - value=3, - range=(0, 10, 1), - ), - desc.IntParam( - name="minNumOfConsistentCamsWithLowSimilarity", - label="Min Consistent Cameras Bad Similarity", - description="Minimum number of consistent cameras for pixels with weak similarity value.", - value=4, - range=(0, 10, 1), - ), - desc.FloatParam( - name="pixToleranceFactor", - label="Tolerance Size", - description="Filtering tolerance size factor, in pixels.", - value=2.0, - range=(0.001, 10.0, 0.1), - advanced=True, - ), - desc.IntParam( - name="pixSizeBall", - label="Filtering Size", - description="Filtering size in pixels.", - value=0, - range=(0, 10, 1), - advanced=True, - ), - desc.IntParam( - name="pixSizeBallWithLowSimilarity", - label="Filtering Size Bad Similarity", - description="Filtering size in pixels for low similarity.", - value=0, - range=(0, 10, 1), - advanced=True, - ), - desc.BoolParam( - name="computeNormalMaps", - label="Compute Normal Maps", - description="Compute normal maps for each depth map.", - value=False, - advanced=True, - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="output", - label="Filtered Depth Maps Folder", - description="Output folder for generated depth maps.", - value="{nodeCacheFolder}" - ), - # these attributes are only here to describe more accurately the output of the node - # by specifying that it generates 2 sequences of images - # (see in Viewer2D.qml how these attributes can be used) - desc.File( - name="depth", - label="Depth Maps", - description="Filtered depth maps.", - semantic="image", - value="{nodeCacheFolder}/_depthMap.exr", - group="", # do not export on the command line - ), - desc.File( - name="sim", - label="Sim Maps", - description="Filtered sim maps.", - semantic="image", - value="{nodeCacheFolder}/_simMap.exr", - group="", # do not export on the command line - ), - desc.File( - name="normal", - label="Normal Maps", - description="Normal maps.", - semantic="image", - value="{nodeCacheFolder}/_normalMap.exr", - enabled=lambda node: node.computeNormalMaps.value, - group="", # do not export on the command line - ), - ] diff --git a/meshroom/nodes/aliceVision/DepthMapRendering.py b/meshroom/nodes/aliceVision/DepthMapRendering.py deleted file mode 100644 index fa071c0489..0000000000 --- a/meshroom/nodes/aliceVision/DepthMapRendering.py +++ /dev/null @@ -1,60 +0,0 @@ -__version__ = "1.0" - -from meshroom.core import desc -from meshroom.core.utils import VERBOSE_LEVEL - - -class DepthMapRendering(desc.AVCommandLineNode): - commandLine = "aliceVision_depthMapRendering {allParams}" - - category = "Utils" - documentation = """ - Using camera parameters and mesh, render depthmaps for each view - """ - - inputs = [ - desc.File( - name="input", - label="Input SfMData", - description="Input SfMData file.", - value="", - ), - desc.File( - name="mesh", - label="Input Mesh", - description="Input mesh file.", - value="", - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="output", - label="Folder", - description="Output folder.", - value="{nodeCacheFolder}", - ), - desc.File( - name="depth", - label="Depth Maps", - description="Rendered depth maps.", - semantic="image", - value="{nodeCacheFolder}/_depthMap.exr", - group="", # do not export on the command line - ), - desc.File( - name="mask", - label="Masks", - description="Masks.", - semantic="image", - value="{nodeCacheFolder}/_mask.exr", - group="", # do not export on the command line - ), - ] diff --git a/meshroom/nodes/aliceVision/DistortionCalibration.py b/meshroom/nodes/aliceVision/DistortionCalibration.py deleted file mode 100644 index 8276ace659..0000000000 --- a/meshroom/nodes/aliceVision/DistortionCalibration.py +++ /dev/null @@ -1,64 +0,0 @@ -__version__ = '5.0' - -from meshroom.core import desc -from meshroom.core.utils import VERBOSE_LEVEL - - -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. -''' - - inputs = [ - desc.File( - name="input", - label="Input SfMData", - description="SfMData file.", - value="", - ), - desc.File( - name="checkerboards", - label="Checkerboards Folder", - description="Folder containing checkerboard JSON files.", - value="", - ), - desc.ChoiceParam( - name="undistortionModelName", - label="Undistortion Model", - description="model used to estimate undistortion.", - value="3deanamorphic4", - values=["3deanamorphic4", "3declassicld", "3deradial4"], - ), - desc.BoolParam( - name="handleSqueeze", - label="Handle Squeeze", - description="Estimate squeeze.", - value=True, - ), - desc.BoolParam( - name="isDesqueezed", - label="Is Desqueezed", - description="True if the input image is already desqueezed.", - value=False, - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="output", - label="SfMData File", - description="Path to the output SfMData file.", - value="{nodeCacheFolder}/sfmData.sfm", - ), - ] diff --git a/meshroom/nodes/aliceVision/ExportAnimatedCamera.py b/meshroom/nodes/aliceVision/ExportAnimatedCamera.py deleted file mode 100644 index 50ca8d0996..0000000000 --- a/meshroom/nodes/aliceVision/ExportAnimatedCamera.py +++ /dev/null @@ -1,111 +0,0 @@ -__version__ = "2.0" - -from meshroom.core import desc -from meshroom.core.utils import VERBOSE_LEVEL - - -class ExportAnimatedCamera(desc.AVCommandLineNode): - commandLine = 'aliceVision_exportAnimatedCamera {allParams}' - size = desc.DynamicNodeSize('input') - - category = 'Export' - documentation = ''' -Convert cameras from an SfM scene into an animated cameras in Alembic file format. -Based on the input image filenames, it will recognize the input video sequence to create an animated camera. -''' - - inputs = [ - desc.File( - name="input", - label="Input SfMData", - description="SfMData file containing a complete SfM.", - value="", - ), - desc.File( - name="sfmDataFilter", - label="SfMData Filter", - description="Filter out cameras from the export if they are part of this SfMData.\n" - "If empty, export all cameras.", - value="", - ), - desc.File( - name="viewFilter", - label="View Filter", - description="Select the cameras to export using an expression based on the image filepath.\n" - "If empty, export all cameras.", - value="", - ), - desc.BoolParam( - name="exportSTMaps", - label="Export ST Maps", - description="Export ST maps. Motion (x, y) is encoded in the image channels to correct the lens distortion.\n" - "It represents the absolute pixel positions of an image normalized between 0 and 1.", - value=True, - ), - desc.BoolParam( - name="exportUndistortedImages", - label="Export Undistorted Images", - description="Export undistorted images.", - value=False, - ), - desc.ChoiceParam( - name="undistortedImageType", - label="Undistort Image Format", - description="Image file format to use for undistorted images ('jpg', 'png', 'tif', 'exr (half)').", - value="exr", - values=["jpg", "png", "tif", "exr"], - enabled=lambda node: node.exportUndistortedImages.value, - ), - desc.BoolParam( - name="exportFullROD", - label="Export Full ROD", - description="Export full ROD.", - value=False, - enabled=lambda node: node.exportUndistortedImages.value and node.undistortedImageType.value == "exr", - ), - desc.BoolParam( - name="correctPrincipalPoint", - label="Correct Principal Point", - description="Correct principal point.", - value=False, - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="output", - label="Folder", - description="Output folder with animated camera and undistorted images.", - value="{nodeCacheFolder}", - ), - desc.File( - name="outputCamera", - label="Camera", - description="Output filename for the animated camera in Alembic format.", - value="{nodeCacheFolder}/camera.abc", - group="", # exclude from command line - ), - desc.File( - name="outputUndistorted", - label="Undistorted Folder", - description="Output undistorted folder.", - value="{nodeCacheFolder}/undistort/", - group="", # exclude from command line - ), - desc.File( - name="outputImages", - label="Undistorted Images", - description="Output undistorted images.", - value="{nodeCacheFolder}/undistort/_.{undistortedImageTypeValue}", - semantic="image", - group="", # exclude from command line - enabled=lambda node: node.exportUndistortedImages.value, - ), - ] diff --git a/meshroom/nodes/aliceVision/ExportColoredPointCloud.py b/meshroom/nodes/aliceVision/ExportColoredPointCloud.py deleted file mode 100644 index 9ffa194fbe..0000000000 --- a/meshroom/nodes/aliceVision/ExportColoredPointCloud.py +++ /dev/null @@ -1,37 +0,0 @@ -__version__ = "1.0" - -from meshroom.core import desc -from meshroom.core.utils import VERBOSE_LEVEL - - -class ExportColoredPointCloud(desc.AVCommandLineNode): - commandLine = 'aliceVision_exportColoredPointCloud {allParams}' - - category = 'Export' - documentation = ''' - ''' - - inputs = [ - desc.File( - name="input", - label="Input SfMData", - description="SfMData file containing a complete SfM.", - value="", - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="output", - label="Point Cloud Filepath", - description="Output point cloud with visibilities as SfMData file.", - value="{nodeCacheFolder}/pointCloud.abc", - ), - ] diff --git a/meshroom/nodes/aliceVision/ExportDistortion.py b/meshroom/nodes/aliceVision/ExportDistortion.py deleted file mode 100644 index 902b865d01..0000000000 --- a/meshroom/nodes/aliceVision/ExportDistortion.py +++ /dev/null @@ -1,99 +0,0 @@ -__version__ = "2.0" - -from meshroom.core import desc -from meshroom.core.utils import VERBOSE_LEVEL - - -class ExportDistortion(desc.AVCommandLineNode): - commandLine = "aliceVision_exportDistortion {allParams}" - - category = "Export" - documentation = """ -Export the lens distortion model as Nuke node and STMaps. -It also allows to export an undistorted image of the lens grids for validation. -""" - - inputs = [ - desc.File( - name="input", - label="Input SfMData", - description="Input SfMData file.", - value="", - ), - desc.BoolParam( - name="exportNukeNode", - label="Export Nuke Node", - description="Export Nuke LensDistortion node as nuke file.\n" - "Only supports 3DEqualizer lens models.", - value=True, - ), - desc.BoolParam( - name="exportAnimatedNukeNode", - label="Export Animated Nuke Node", - description="Export animated distortion for this sequence as nuke file.", - value=False, - ), - desc.BoolParam( - name="exportLensGridsUndistorted", - label="Export Lens Grids Undistorted", - description="Export the lens grids undistorted for validation.", - value=True, - ), - desc.BoolParam( - name="exportSTMaps", - label="Export STMaps", - description="Export STMaps for distortion and undistortion.", - value=True, - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="output", - label="Folder", - description="Output folder.", - value="{nodeCacheFolder}", - ), - desc.File( - name="distortionNukeNode", - label="Distortion Nuke Node", - description="Calibrated distortion ST map.", - value="{nodeCacheFolder}/nukeLensDistortion_.nk", - group="", # do not export on the command line - enabled=lambda node: node.exportNukeNode.value, - ), - desc.File( - name="lensGridsUndistorted", - label="Undistorted Lens Grids", - description="Undistorted lens grids for validation", - semantic="image", - value="{nodeCacheFolder}/lensgrid__undistort.exr", - group="", # do not export on the command line - enabled=lambda node: node.exportLensGridsUndistorted.value, - ), - desc.File( - name="distortionStMap", - label="Distortion ST Map", - description="Calibrated distortion ST map.", - semantic="image", - value="{nodeCacheFolder}/stmap__distort.exr", - group="", # do not export on the command line - enabled=lambda node: node.exportSTMaps.value, - ), - desc.File( - name="undistortionStMap", - label="Undistortion ST Map", - description="Calibrated undistortion ST map.", - semantic="image", - value="{nodeCacheFolder}/stmap__undistort.exr", - group="", # do not export on the command line - enabled=lambda node: node.exportSTMaps.value, - ), - ] diff --git a/meshroom/nodes/aliceVision/ExportImages.py b/meshroom/nodes/aliceVision/ExportImages.py deleted file mode 100644 index 029b1092c9..0000000000 --- a/meshroom/nodes/aliceVision/ExportImages.py +++ /dev/null @@ -1,83 +0,0 @@ -__version__ = "1.0" - -from meshroom.core import desc -from meshroom.core.utils import VERBOSE_LEVEL - - -class ExportImages(desc.AVCommandLineNode): - commandLine = 'aliceVision_exportImages {allParams}' - size = desc.DynamicNodeSize('input') - parallelization = desc.Parallelization(blockSize=40) - commandLineRange = '--rangeStart {rangeStart} --rangeSize {rangeBlockSize}' - - category = 'Export' - documentation = ''' - Export images referenced in the input sfmData by transforming - them to adapt to the required target intrinsics. For example, the target - intrinsics may be the same without the distortion. - ''' - - inputs = [ - desc.File( - name="input", - label="SfMData", - description="Input SfMData file. Contains the original intrinsics of the images.", - value="", - ), - desc.File( - name="target", - label="Target", - description="This sfmData file contains the required intrinsics for the output images.", - value="", - ), - desc.ChoiceParam( - name="outputFileType", - label="Output File Type", - description="Output file type for the exported images.", - value="exr", - values=["jpg", "png", "tif", "exr"], - advanced=True, - ), - desc.BoolParam( - name="evCorrection", - label="Correct Images Exposure", - description="Apply a correction on images' exposure value.", - value=False, - advanced=True, - ), - desc.ChoiceParam( - name="namingMode", - label="Naming mode", - description="image naming mode :\n" - " - viewid: viewid.ext.\n" - " - frameid: Frameid.ext.\n" - " - keep: Keep original name.\n", - value="frameid", - values=["viewid", "frameid", "keep"], - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="output", - label="Images Folder", - description="Output folder.", - value="{nodeCacheFolder}", - ), - desc.File( - name="undistorted", - label="Undistorted Images", - description="List of undistorted images.", - semantic="image", - value="{nodeCacheFolder}/.{outputFileTypeValue}", - group="", - advanced=True, - ), - ] diff --git a/meshroom/nodes/aliceVision/ExportMatches.py b/meshroom/nodes/aliceVision/ExportMatches.py deleted file mode 100644 index 6e10487eea..0000000000 --- a/meshroom/nodes/aliceVision/ExportMatches.py +++ /dev/null @@ -1,81 +0,0 @@ -__version__ = "2.0" - -from meshroom.core import desc -from meshroom.core.utils import DESCRIBER_TYPES, VERBOSE_LEVEL - - -class ExportMatches(desc.AVCommandLineNode): - commandLine = 'aliceVision_exportMatches {allParams}' - size = desc.DynamicNodeSize('input') - - category = 'Export' - documentation = ''' - ''' - - inputs = [ - desc.File( - name="input", - label="Input", - description="SfMData file.", - value="", - ), - desc.ChoiceParam( - name="describerTypes", - label="Describer Types", - description="Describer types used to describe an image.", - values=DESCRIBER_TYPES, - value=["dspsift"], - exclusive=False, - joinChar=",", - ), - desc.ListAttribute( - elementDesc=desc.File( - name="featuresFolder", - label="Features Folder", - description="Folder containing some extracted features and descriptors.", - value="", - ), - name="featuresFolders", - label="Features Folders", - description="Folder(s) containing the extracted features and descriptors.", - ), - desc.ListAttribute( - elementDesc=desc.File( - name="matchesFolder", - label="Matches Folder", - description="Folder containing some computed matches.", - value="", - ), - name="matchesFolders", - label="Matches Folders", - description="Folder(s) in which computed matches are stored.", - ), - desc.File( - name="filterA", - label="Filter A", - description="One item of the pair must match this.", - value="", - ), - desc.File( - name="filterB", - label="Filter B", - description="One item of the pair must match this.", - value="", - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="output", - label="Folder", - description="Output path for the features and descriptors files (*.feat, *.desc).", - value="{nodeCacheFolder}", - ), - ] diff --git a/meshroom/nodes/aliceVision/ExportMaya.py b/meshroom/nodes/aliceVision/ExportMaya.py deleted file mode 100644 index 1b46005d42..0000000000 --- a/meshroom/nodes/aliceVision/ExportMaya.py +++ /dev/null @@ -1,222 +0,0 @@ -__version__ = "1.0" - -from meshroom.core import desc -from meshroom.core.utils import VERBOSE_LEVEL - -class ExportMaya(desc.Node): - - category = 'Export' - documentation = ''' - Export a Maya script. - This script executed inside Maya, will gather the Meshroom computed elements. - ''' - - inputs = [ - desc.File( - name="input", - label="Input SfMData", - description="Input SfMData file.", - value="", - ), - desc.File( - name="alembic", - label="Alembic File", - description="Input alembic file.", - value="", - ), - desc.File( - name="mesh", - label="Input Mesh", - description="Input mesh file.", - value="", - ), - desc.File( - name="images", - label="Undistorted Images", - description="Undistorted images template.", - value="", - ), - desc.BoolParam( - name="generateMaya", - label="Generate Maya Scene", - description="Select to generate the Maya scene in addition to the export of the mel script.", - value=True, - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="meloutput", - label="Mel Script", - description="Generated mel script.", - value="{nodeCacheFolder}/import.mel", - ), - desc.File( - name="mayaoutput", - label="Maya Scene", - description="Generated Maya scene.", - value="{nodeCacheFolder}/scene.mb", - enabled=lambda node: node.generateMaya.value, - ), - ] - - def processChunk(self, chunk): - - import pyalicevision - import pathlib - import inspect - import subprocess - - chunk.logManager.start(chunk.node.verboseLevel.value) - - chunk.logger.info("Open input file") - data = pyalicevision.sfmData.SfMData() - ret = pyalicevision.sfmDataIO.load(data, chunk.node.input.value, pyalicevision.sfmDataIO.ALL) - if not ret: - chunk.logger.error("Cannot open input") - chunk.logManager.end() - raise RuntimeError() - - #Check that we have Only one intrinsic - intrinsics = data.getIntrinsics() - if len(intrinsics) > 1: - chunk.logger.error("Only project with a single intrinsic are supported") - chunk.logManager.end() - raise RuntimeError() - - intrinsicId = next(iter(intrinsics)) - intrinsic = intrinsics[intrinsicId] - w = intrinsic.w() - h = intrinsic.h() - - cam = pyalicevision.camera.Pinhole.cast(intrinsic) - if cam == None: - chunk.logger.error("Intrinsic is not a required pinhole model") - chunk.logManager.end() - raise RuntimeError() - - offset = cam.getOffset() - pix2inches = cam.sensorWidth() / (25.4 * max(w, h)); - ox = -pyalicevision.numeric.getX(offset) * pix2inches - oy = pyalicevision.numeric.getY(offset) * pix2inches - - scale = cam.getScale() - fx = pyalicevision.numeric.getX(scale) - fy = pyalicevision.numeric.getY(scale) - - - #Retrieve the first frame - - minIntrinsicId = 0 - minFrameId = 0 - minFrameName = '' - first = True - views = data.getViews() - - for viewId in views: - - view = views[viewId] - frameId = view.getFrameId() - intrinsicId = view.getIntrinsicId() - frameName = pathlib.Path(view.getImageInfo().getImagePath()).stem - - if first or frameId < minFrameId: - minFrameId = frameId - minIntrinsicId = intrinsicId - minFrameName = frameName - first = False - - - #Generate the script itself - mayaFileName = chunk.node.mayaoutput.value - header = f''' - file -f -new; - ''' - - footer = f''' - file -rename "{mayaFileName}"; - file -type "mayaBinary"; - file -save; - ''' - - alembic = chunk.node.alembic.value - abcString = f'AbcImport -mode open -fitTimeRange "{alembic}";' - - mesh = chunk.node.mesh.value - objString = f'file -import -type "OBJ" -ignoreVersion -ra true -mbl true -mergeNamespacesOnClash false -namespace "mesh" -options "mo=1" -pr -importTimeRange "combine" "{mesh}";' - - framePath = chunk.node.images.value.replace('', str(minIntrinsicId)).replace('', minFrameName) - - camString = f''' - select -r mvgCameras ; - string $camName[] = `listRelatives`; - - currentTime {minFrameId}; - - imagePlane -c $camName[0] -fileName "{framePath}"; - - setAttr "imagePlaneShape1.useFrameExtension" 1; - setAttr "imagePlaneShape1.offsetX" {ox}; - setAttr "imagePlaneShape1.offsetY" {oy}; - ''' - - ipa = fx / fy - advCamString = '' - - if abs(ipa - 1.0) < 1e-6: - advCamString = f''' - setAttr "imagePlaneShape1.fit" 1; - ''' - else: - advCamString = f''' - setAttr "imagePlaneShape1.fit" 4; - setAttr "imagePlaneShape1.squeezeCorrection" {ipa}; - - select -r $camName[0]; - float $vaperture = `getAttr ".verticalFilmAperture"`; - float $scaledvaperture = $vaperture * {ipa}; - setAttr "imagePlaneShape1.sizeY" $scaledvaperture; - ''' - - with open(chunk.node.meloutput.value, "w") as f: - if chunk.node.generateMaya.value: - f.write(inspect.cleandoc(header) + '\n') - f.write(inspect.cleandoc(abcString) + '\n') - f.write(inspect.cleandoc(objString) + '\n') - f.write(inspect.cleandoc(camString) + '\n') - f.write(inspect.cleandoc(advCamString) + '\n') - if chunk.node.generateMaya.value: - f.write(inspect.cleandoc(footer) + '\n') - - chunk.logger.info("Mel Script generated") - - #Export to maya - if chunk.node.generateMaya.value: - try: - melPath = chunk.node.meloutput.value - cmd = f'maya_batch -batch -script "{melPath}"' - p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - stdout, stderr = p.communicate() - - if len(stdout) > 0: - chunk.logger.info(stdout.decode()) - - rc = p.returncode - if rc != 0: - chunk.logger.error(stderr.decode()) - raise Exception(rc) - - except Exception as e: - chunk.logger.error('Failed to run maya batch : "{}".'.format(str(e))) - raise RuntimeError() - - chunk.logger.info("Maya Scene generated") - - chunk.logManager.end() diff --git a/meshroom/nodes/aliceVision/ExportUSD.py b/meshroom/nodes/aliceVision/ExportUSD.py deleted file mode 100644 index c452fde28d..0000000000 --- a/meshroom/nodes/aliceVision/ExportUSD.py +++ /dev/null @@ -1,46 +0,0 @@ -__version__ = "1.0" - -from meshroom.core import desc -from meshroom.core.utils import VERBOSE_LEVEL - - -class ExportUSD(desc.AVCommandLineNode): - commandLine = 'aliceVision_exportUSD {allParams}' - size = desc.DynamicNodeSize('input') - - category = 'Utils' - documentation = ''' - Export a mesh (OBJ file) to USD format. - ''' - - inputs = [ - desc.File( - name="input", - label="Input", - description="Input mesh file.", - value="", - ), - desc.ChoiceParam( - name="fileType", - label="USD File Format", - description="Output USD file format.", - value="usda", - values=["usda", "usdc", "usdz"] - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="output", - label="Output", - description="Path to the output file.", - value="{nodeCacheFolder}/output.{fileTypeValue}", - ), - ] diff --git a/meshroom/nodes/aliceVision/ExtractMetadata.py b/meshroom/nodes/aliceVision/ExtractMetadata.py deleted file mode 100644 index 0631a65b09..0000000000 --- a/meshroom/nodes/aliceVision/ExtractMetadata.py +++ /dev/null @@ -1,133 +0,0 @@ -__version__ = "0.1" - -from meshroom.core import desc -from meshroom.core.utils import VERBOSE_LEVEL -from pathlib import Path - -import pyalicevision as av - -import distutils.dir_util as du -import shutil -import glob -import os -import subprocess - - -class ExtractMetadata(desc.Node): - size = desc.DynamicNodeSize("input") - - category = 'Utils' - documentation = ''' -Using exifTool, this node extracts metadata of all images referenced in a sfmData and store them in appropriate files. -''' - - inputs = [ - desc.File( - name="input", - label="Input", - description="SfMData input file.", - value="", - ), - desc.BoolParam( - name="keepFilename", - label="Keep Filename", - description="Keep the filename of the inputs for the outputs.", - value=False, - ), - desc.ChoiceParam( - name="extension", - label="Output File Extension", - description="Metadata file extension.", - value="txt", - values=["txt", "xml", "xmp"], - exclusive=True, - ), - desc.StringParam( - name="arguments", - label="Arguments", - description="ExifTool command arguments.", - value="", - ), - desc.BoolParam( - name="insertInSfm", - label="Update sfmData", - description="Insert the extracted metadata in the sfmData file.", - value=False, - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="output", - label="Result Folder", - description="Output path for the resulting metadata files.", - value="{nodeCacheFolder}", - ), - ] - - def processChunk(self, chunk): - try: - chunk.logManager.start(chunk.node.verboseLevel.value) - - if chunk.node.input.value == "" or chunk.node.input.value[-4:].lower() != '.sfm': - error = 'This node need to have a sfmData connected as input.' - chunk.logger.error(error) - raise RuntimeError(error) - - if not os.path.exists(chunk.node.output.value): - os.mkdir(chunk.node.output.value) - - dataAV = av.sfmData.SfMData() - if av.sfmDataIO.load(dataAV, chunk.node.input.value, av.sfmDataIO.ALL): - views = dataAV.getViews() - for id, v in views.items(): - inputFile = v.getImage().getImagePath() - chunk.logger.info(f"Processing {inputFile}") - - if chunk.node.keepFilename.value: - outputMetadataFilename = os.path.join(chunk.node.output.value, Path(inputFile).stem + "." + chunk.node.extension.value) - else: - outputMetadataFilename = os.path.join(chunk.node.output.value, str(id) + "." + chunk.node.extension.value) - - if chunk.node.extension.value == 'txt': - cmd = 'exiftool ' + chunk.node.arguments.value.strip() + ' ' + inputFile + ' > ' + outputMetadataFilename - elif chunk.node.extension.value == 'xml': - cmd = 'exiftool -X ' + chunk.node.arguments.value.strip() + ' ' + inputFile + ' > ' + outputMetadataFilename - else: #xmp - cmd = 'exiftool -tagsfromfile ' + inputFile + ' ' + chunk.node.arguments.value.strip() + ' ' + outputMetadataFilename - - chunk.logger.debug(cmd) - error = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).stderr.read().decode() - - chunk.logger.debug(error) - - if error != "": - chunk.logger.error(error) - raise RuntimeError(error) - if not os.path.exists(outputMetadataFilename): - info = 'No metadata extracted for file ' + inputFile - chunk.logger.info(info) - elif chunk.node.insertInSfm.value: - cmd = 'exiftool ' + chunk.node.arguments.value.strip() + ' ' + inputFile - metadata = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).stdout.read().decode() - chunk.logger.debug(metadata) - lmeta = metadata.split('\n') - for i in range(1, len(lmeta)-1): - l = lmeta[i].split(':', 1) - v.getImageInfo().addMetadata('ExifTool:'+l[0].strip(), l[1].strip()) - - if chunk.node.insertInSfm.value: - outputSfm = os.path.join(chunk.node.output.value, Path(chunk.node.input.value).stem + ".sfm") - av.sfmDataIO.save(dataAV, outputSfm, av.sfmDataIO.ALL) - - chunk.logger.info('Metadata extraction end') - - finally: - chunk.logManager.end() diff --git a/meshroom/nodes/aliceVision/FeatureExtraction.py b/meshroom/nodes/aliceVision/FeatureExtraction.py deleted file mode 100644 index 91cba12c86..0000000000 --- a/meshroom/nodes/aliceVision/FeatureExtraction.py +++ /dev/null @@ -1,165 +0,0 @@ -__version__ = "1.3" - -from meshroom.core import desc -from meshroom.core.utils import COLORSPACES, DESCRIBER_TYPES, VERBOSE_LEVEL - - -class FeatureExtraction(desc.AVCommandLineNode): - commandLine = 'aliceVision_featureExtraction {allParams}' - size = desc.DynamicNodeSize('input') - parallelization = desc.Parallelization(blockSize=40) - commandLineRange = '--rangeStart {rangeStart} --rangeSize {rangeBlockSize}' - - category = 'Sparse Reconstruction' - documentation = ''' -This node extracts distinctive groups of pixels that are, to some extent, invariant to changing camera viewpoints during image acquisition. -Hence, a feature in the scene should have similar feature descriptions in all images. - -This node implements multiple methods: - * **SIFT** -The most standard method. This is the default and recommended value for all use cases. - * **AKAZE** -AKAZE can be interesting solution to extract features in challenging condition. It could be able to match wider angle than SIFT but has drawbacks. -It may extract too many features, the repartition is not always good. -It is known to be good on challenging surfaces such as skin. - * **CCTAG** -CCTag is a marker type with 3 or 4 crowns. You can put markers in the scene during the shooting session to automatically re-orient and re-scale the scene to a known size. -It is robust to motion-blur, depth-of-field, occlusion. Be careful to have enough white margin around your CCTags. - - -## Online -[https://alicevision.org/#photogrammetry/natural_feature_extraction](https://alicevision.org/#photogrammetry/natural_feature_extraction) -''' - - inputs = [ - desc.File( - name="input", - label="SfMData", - description="Input SfMData file.", - value="", - ), - desc.File( - name="masksFolder", - label="Masks Folder", - description="Use masks to filter features. Filename should be the same or the image UID.", - value="", - ), - desc.ChoiceParam( - name="maskExtension", - label="Mask Extension", - description="File extension for masks.", - value="png", - values=["png", "exr", "jpg"], - ), - desc.BoolParam( - name="maskInvert", - label="Invert Masks", - description="Invert mask values.", - value=False, - ), - desc.ChoiceParam( - name="describerTypes", - label="Describer Types", - description="Describer types used to describe an image.", - values=DESCRIBER_TYPES, - value=["dspsift"], - exclusive=False, - joinChar=",", - exposed=True, - ), - desc.ChoiceParam( - name="describerPreset", - label="Describer Density", - description="Control the ImageDescriber density (low, medium, normal, high, ultra).\n" - "Warning: Use ULTRA only on small datasets.", - value="normal", - values=["low", "medium", "normal", "high", "ultra", "custom"], - group=lambda node: 'allParams' if node.describerPreset.value != 'custom' else None, - ), - desc.IntParam( - name="maxNbFeatures", - label="Max Nb Features", - description="Maximum number of features extracted (0 means default value based on Describer Density).", - value=0, - range=(0, 100000, 1000), - advanced=True, - enabled=lambda node: (node.describerPreset.value == "custom"), - ), - desc.ChoiceParam( - name="describerQuality", - label="Describer Quality", - description="Control the ImageDescriber quality (low, medium, normal, high, ultra).", - value="normal", - values=["low", "medium", "normal", "high", "ultra"], - ), - desc.ChoiceParam( - name="contrastFiltering", - label="Contrast Filtering", - description="Contrast filtering method to ignore features with too low contrast that can be considered as noise:\n" - " - Static: Fixed threshold.\n" - " - AdaptiveToMedianVariance: Based on image content analysis.\n" - " - NoFiltering: Disable contrast filtering.\n" - " - GridSortOctaves: Grid Sort but per octaves (and only per scale at the end).\n" - " - GridSort: Grid sort per octaves and at the end (scale * peakValue).\n" - " - GridSortScaleSteps: Grid sort per octaves and at the end (scale and then peakValue).\n" - " - NonExtremaFiltering: Filter non-extrema peakValues.\n", - value="GridSort", - values=["Static", "AdaptiveToMedianVariance", "NoFiltering", "GridSortOctaves", "GridSort", "GridSortScaleSteps", "GridSortOctaveSteps", "NonExtremaFiltering"], - advanced=True, - ), - desc.FloatParam( - name="relativePeakThreshold", - label="Relative Peak Threshold", - description="Peak threshold relative to median of gradients.", - value=0.01, - range=(0.01, 1.0, 0.001), - advanced=True, - enabled=lambda node: (node.contrastFiltering.value == "AdaptiveToMedianVariance"), - ), - desc.BoolParam( - name="gridFiltering", - label="Grid Filtering", - description="Enable grid filtering. Highly recommended to ensure usable number of features.", - value=True, - advanced=True, - ), - desc.ChoiceParam( - name="workingColorSpace", - label="Working Color Space", - description="Allows you to choose the color space in which the data are processed.", - values=COLORSPACES, - value="sRGB", - ), - desc.BoolParam( - name="forceCpuExtraction", - label="Force CPU Extraction", - description="Use only CPU feature extraction.", - value=True, - advanced=True, - ), - desc.IntParam( - name="maxThreads", - label="Max Nb Threads", - description="Maximum number of threads to run simultaneously (0 for automatic mode).", - value=0, - range=(0, 24, 1), - invalidate=False, - advanced=True, - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="output", - label="Features Folder", - description="Output path for the features and descriptors files (*.feat, *.desc).", - value="{nodeCacheFolder}", - ), - ] diff --git a/meshroom/nodes/aliceVision/FeatureMatching.py b/meshroom/nodes/aliceVision/FeatureMatching.py deleted file mode 100644 index a8bc0e19a4..0000000000 --- a/meshroom/nodes/aliceVision/FeatureMatching.py +++ /dev/null @@ -1,210 +0,0 @@ -__version__ = "2.0" - -from meshroom.core import desc -from meshroom.core.utils import DESCRIBER_TYPES, VERBOSE_LEVEL - - -class FeatureMatching(desc.AVCommandLineNode): - commandLine = 'aliceVision_featureMatching {allParams}' - size = desc.DynamicNodeSize('input') - parallelization = desc.Parallelization(blockSize=20) - commandLineRange = '--rangeStart {rangeStart} --rangeSize {rangeBlockSize}' - - category = 'Sparse Reconstruction' - documentation = ''' -This node performs the matching of all features between the candidate image pairs. - -It is performed in 2 steps: - - 1/ **Photometric Matches** - -It performs the photometric matches between the set of features descriptors from the 2 input images. -For each feature descriptor on the first image, it looks for the 2 closest descriptors in the second image and uses a relative threshold between them. -This assumption kill features on repetitive structure but has proved to be a robust criterion. - - 2/ **Geometric Filtering** - -It performs a geometric filtering of the photometric match candidates. -It uses the features positions in the images to make a geometric filtering by using epipolar geometry in an outlier detection framework -called RANSAC (RANdom SAmple Consensus). It randomly selects a small set of feature correspondences and compute the fundamental (or essential) matrix, -then it checks the number of features that validates this model and iterate through the RANSAC framework. - -## Online -[https://alicevision.org/#photogrammetry/feature_matching](https://alicevision.org/#photogrammetry/feature_matching) -''' - - inputs = [ - desc.File( - name="input", - label="SfMData", - description="Input SfMData file.", - value="", - ), - desc.ListAttribute( - elementDesc=desc.File( - name="featuresFolder", - label="Features Folder", - description="Folder containing some extracted features and descriptors.", - value="", - ), - name="featuresFolders", - label="Features Folders", - description="Folder(s) containing the extracted features and descriptors.", - exposed=True, - ), - desc.File( - name="imagePairsList", - label="Image Pairs", - description="Path to a file which contains the list of image pairs to match.", - value="", - ), - desc.ChoiceParam( - name="describerTypes", - label="Describer Types", - description="Describer types used to describe an image.", - values=DESCRIBER_TYPES, - value=["dspsift"], - exclusive=False, - joinChar=",", - exposed=True, - ), - desc.ChoiceParam( - name="photometricMatchingMethod", - label="Photometric Matching Method", - description="For scalar based regions descriptors:\n" - " - BRUTE_FORCE_L2: L2 BruteForce matching\n" - " - ANN_L2: L2 Approximate Nearest Neighbor matching\n" - " - CASCADE_HASHING_L2: L2 Cascade Hashing matching\n" - " - FAST_CASCADE_HASHING_L2: L2 Cascade Hashing with precomputed hashed regions (faster than CASCADE_HASHING_L2 but use more memory)\n" - "For Binary based descriptors:\n" - " - BRUTE_FORCE_HAMMING: BruteForce Hamming matching", - value="ANN_L2", - values=["BRUTE_FORCE_L2", "ANN_L2", "CASCADE_HASHING_L2", "FAST_CASCADE_HASHING_L2", "BRUTE_FORCE_HAMMING"], - advanced=True, - ), - desc.ChoiceParam( - name="geometricEstimator", - label="Geometric Estimator", - description="Geometric estimator:\n" - " - acransac: A-Contrario Ransac.\n" - " - loransac: LO-Ransac (only available for 'fundamental_matrix' model).", - value="acransac", - values=["acransac", "loransac"], - advanced=True, - ), - desc.ChoiceParam( - name="geometricFilterType", - label="Geometric Filter Type", - description="Geometric validation method to filter features matches:\n" - " - fundamental_matrix\n" - " - fundamental_with_distortion\n" - " - essential_matrix\n" - " - homography_matrix\n" - " - homography_growing\n" - " - no_filtering", - value="fundamental_matrix", - values=["fundamental_matrix", "fundamental_with_distortion", "essential_matrix", "homography_matrix", "homography_growing", "no_filtering"], - advanced=True, - ), - desc.FloatParam( - name="distanceRatio", - label="Distance Ratio", - description="Distance ratio to discard non meaningful matches.", - value=0.8, - range=(0.0, 1.0, 0.01), - advanced=True, - ), - desc.IntParam( - name="maxIteration", - label="Max Iterations", - description="Maximum number of iterations allowed in the Ransac step.", - value=50000, - range=(1, 100000, 1), - advanced=True, - ), - desc.FloatParam( - name="geometricError", - label="Geometric Validation Error", - description="Maximum error (in pixels) allowed for features matching during geometric verification.\n" - "If set to 0, it will select a threshold according to the localizer estimator used\n" - "(if ACRansac, it will analyze the input data to select the optimal value).", - value=0.0, - range=(0.0, 10.0, 0.1), - advanced=True, - ), - desc.FloatParam( - name="knownPosesGeometricErrorMax", - label="Known Poses Geometric Error Max", - description="Maximum error (in pixels) allowed for features matching guided by geometric information from known camera poses.\n" - "If set to 0 it lets the ACRansac select an optimal value.", - value=5.0, - range=(0.0, 100.0, 1.0), - advanced=True, - ), - desc.FloatParam( - name="minRequired2DMotion", - label="Minimal 2D Motion", - description="Filter out matches without enough 2D motion (threshold in pixels).\n" - "Use -1 to disable this filter.\n" - "Useful for filtering the background during acquisition with a turntable and a static camera.", - value=-1.0, - range=(0.0, 10.0, 1.0), - ), - desc.IntParam( - name="maxMatches", - label="Max Matches", - description="Maximum number of matches to keep.", - value=0, - range=(0, 10000, 1), - advanced=True, - ), - desc.BoolParam( - name="savePutativeMatches", - label="Save Putative Matches", - description="Save putative matches.", - value=False, - advanced=True, - ), - desc.BoolParam( - name="crossMatching", - label="Cross Matching", - description="Ensure that the matching process is symmetric (same matches for I->J than for J->I).", - value=False, - ), - desc.BoolParam( - name="guidedMatching", - label="Guided Matching", - description="Use the found model to improve the pairwise correspondences.", - value=False, - ), - desc.BoolParam( - name="matchFromKnownCameraPoses", - label="Match From Known Camera Poses", - description="Enable the usage of geometric information from known camera poses to guide the feature matching.\n" - "If some cameras have unknown poses (so there is no geometric prior), the standard feature matching will be performed.", - value=False, - ), - desc.BoolParam( - name="exportDebugFiles", - label="Export Debug Files", - description="Export debug files (svg, dot).", - value=False, - invalidate=False, - advanced=True, - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - outputs = [ - desc.File( - name="output", - label="Matches Folder", - description="Path to a folder in which the computed matches are stored.", - value="{nodeCacheFolder}", - ), - ] diff --git a/meshroom/nodes/aliceVision/FeatureRepeatability.py b/meshroom/nodes/aliceVision/FeatureRepeatability.py deleted file mode 100644 index a57ac67735..0000000000 --- a/meshroom/nodes/aliceVision/FeatureRepeatability.py +++ /dev/null @@ -1,120 +0,0 @@ -__version__ = "1.1" - -from meshroom.core import desc -from meshroom.core.utils import DESCRIBER_TYPES, VERBOSE_LEVEL - - -class FeatureRepeatability(desc.AVCommandLineNode): - commandLine = 'aliceVision_samples_repeatabilityDataset {allParams}' - size = desc.DynamicNodeSize('input') - # parallelization = desc.Parallelization(blockSize=40) - # commandLineRange = '--rangeStart {rangeStart} --rangeSize {rangeBlockSize}' - - category = 'Utils' - documentation = ''' -Compare feature/descriptor matching repeatability on some dataset with known homography motions. -''' - - inputs = [ - desc.File( - name="input", - label="Input Folder", - description="Input folder with evaluation datasets.", - value="", - ), - desc.ChoiceParam( - name="describerTypes", - label="Describer Types", - description="Describer types used to describe an image.", - values=DESCRIBER_TYPES, - value=["sift"], - exclusive=False, - joinChar=",", - ), - desc.ChoiceParam( - name="describerPreset", - label="Describer Density", - description="Control the ImageDescriber density (low, medium, normal, high, ultra).\n" - "Warning: Use ULTRA only on small datasets.", - value="normal", - values=["low", "medium", "normal", "high", "ultra"], - ), - desc.ChoiceParam( - name="describerQuality", - label="Describer Quality", - description="Control the ImageDescriber quality (low, medium, normal, high, ultra).", - value="normal", - values=["low", "medium", "normal", "high", "ultra"], - ), - desc.ChoiceParam( - name="contrastFiltering", - label="Contrast Filtering", - description="Contrast filtering method to ignore features with too low contrast that can be considered as noise:\n" - " - Static: Fixed threshold.\n" - " - AdaptiveToMedianVariance: Based on image content analysis.\n" - " - NoFiltering: Disable contrast filtering.\n" - " - GridSortOctaves: Grid Sort but per octaves (and only per scale at the end).\n" - " - GridSort: Grid sort per octaves and at the end (scale * peakValue).\n" - " - GridSortScaleSteps: Grid sort per octaves and at the end (scale and then peakValue).\n" - " - NonExtremaFiltering: Filter non-extrema peakValues.", - value="Static", - values=["Static", "AdaptiveToMedianVariance", "NoFiltering", "GridSortOctaves", "GridSort", "GridSortScaleSteps", "GridSortOctaveSteps", "NonExtremaFiltering"], - advanced=True, - ), - desc.FloatParam( - name="relativePeakThreshold", - label="Relative Peak Threshold", - description="Peak threashold relative to the median of gradients.", - value=0.01, - range=(0.01, 1.0, 0.001), - advanced=True, - enabled=lambda node: (node.contrastFiltering.value == "AdaptiveToMedianVariance"), - ), - desc.BoolParam( - name="gridFiltering", - label="Grid Filtering", - description="Enable grid filtering. Highly recommended to ensure a usable number of features.", - value=True, - advanced=True, - ), - desc.BoolParam( - name="forceCpuExtraction", - label="Force CPU Extraction", - description="Use only CPU feature extraction.", - value=True, - invalidate=False, - advanced=True, - ), - desc.IntParam( - name="invalidate", - label="Invalidate", - description="Invalidate.", - value=0, - range=(0, 10000, 1), - group="", - ), - desc.StringParam( - name="comments", - label="Comments", - description="Comments.", - value="", - group="", - invalidate=False, - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="output", - label="Folder", - description="Output path for the features and descriptors files (*.feat, *.desc).", - value="{nodeCacheFolder}", - ), - ] diff --git a/meshroom/nodes/aliceVision/GlobalRotationEstimating.py b/meshroom/nodes/aliceVision/GlobalRotationEstimating.py deleted file mode 100644 index 2b2235c1b7..0000000000 --- a/meshroom/nodes/aliceVision/GlobalRotationEstimating.py +++ /dev/null @@ -1,66 +0,0 @@ -__version__ = "1.0" - -from meshroom.core import desc -from meshroom.core.utils import VERBOSE_LEVEL - - -class GlobalRotationEstimating(desc.AVCommandLineNode): - commandLine = "aliceVision_globalRotationEstimating {allParams}" - - category = "Sparse Reconstruction" - documentation = ''' -Estimate the global rotation given tracks. -''' - - inputs = [ - desc.File( - name="input", - label="SfMData", - description="SfMData file.", - value="", - ), - desc.File( - name="tracksFilename", - label="Tracks File", - description="Tracks file.", - value="", - ), - desc.File( - name="pairs", - label="Pairs File", - description="Information on pairs.", - value="", - ), - desc.ChoiceParam( - name="rotationAveragingMethod", - label="Rotation Averaging Method", - description="Method for rotation averaging:\n" - " - L1 minimization\n" - " - L2 minimization", - values=["L1_minimization", "L2_minimization"], - value="L2_minimization", - ), - desc.FloatParam( - name="angularTolerance", - label="Angular Tolerance", - description="Angular (in degrees) tolerance for a given triplet.", - value=5.0, - range=(0.0, 180.0, 1.0), - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="output", - label="SfMData", - description="Path to the output SfMData file.", - value="{nodeCacheFolder}/sfm.abc", - ), - ] diff --git a/meshroom/nodes/aliceVision/GlobalSfM.py b/meshroom/nodes/aliceVision/GlobalSfM.py deleted file mode 100644 index 94521f2bb8..0000000000 --- a/meshroom/nodes/aliceVision/GlobalSfM.py +++ /dev/null @@ -1,111 +0,0 @@ -__version__ = "1.0" - - -from meshroom.core import desc -from meshroom.core.utils import DESCRIBER_TYPES, VERBOSE_LEVEL - - -class GlobalSfM(desc.AVCommandLineNode): - commandLine = "aliceVision_globalSfM {allParams}" - size = desc.DynamicNodeSize("input") - - category = "Sparse Reconstruction" - documentation = """ -Performs the Structure-From-Motion with a global approach. -It is known to be faster but less robust to challenging datasets than the Incremental approach. -""" - - inputs = [ - desc.File( - name="input", - label="SfMData", - description="Input SfMData file.", - value="", - ), - desc.ListAttribute( - elementDesc=desc.File( - name="featuresFolder", - label="Features Folder", - description="Folder containing some extracted features.", - value="", - ), - name="featuresFolders", - label="Features Folders", - description="Folder(s) containing the extracted features.", - ), - desc.ListAttribute( - elementDesc=desc.File( - name="matchesFolder", - label="Matches Folder", - description="Folder containing some computed matches.", - value="", - ), - name="matchesFolders", - label="Matches Folders", - description="Folder(s) in which computed matches are stored.", - ), - desc.ChoiceParam( - name="describerTypes", - label="Describer Types", - description="Describer types used to describe an image.", - values=DESCRIBER_TYPES, - value=["dspsift"], - exclusive=False, - joinChar=",", - ), - desc.ChoiceParam( - name="rotationAveraging", - label="Rotation Averaging Method", - description="Method for rotation averaging:\n" - " - L1 minimization\n" - " - L2 minimization", - values=["L1_minimization", "L2_minimization"], - value="L2_minimization", - ), - desc.ChoiceParam( - name="translationAveraging", - label="Translation Averaging Method", - description="Method for translation averaging:\n" - " - L1 minimization\n" - " - L2 minimization of sum of squared Chordal distances\n" - " - L1 soft minimization", - values=["L1_minimization", "L2_minimization", "L1_soft_minimization"], - value="L1_soft_minimization", - ), - desc.BoolParam( - name="lockAllIntrinsics", - label="Lock All Intrinsic Camera Parameters", - description="Force to keep all the intrinsics parameters of the cameras (focal length, \n" - "principal point, distortion if any) constant during the reconstruction.\n" - "This may be helpful if the input cameras are already fully calibrated.", - value=False, - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="output", - label="SfMData", - description="Path to the output SfMData file.", - value="{nodeCacheFolder}/sfm.abc", - ), - desc.File( - name="outputViewsAndPoses", - label="Output Poses", - description="Path to the output SfMData file with cameras (views and poses).", - value="{nodeCacheFolder}/cameras.sfm", - ), - desc.File( - name="extraInfoFolder", - label="Folder", - description="Folder for intermediate reconstruction files and additional reconstruction information files.", - value="{nodeCacheFolder}", - ), - ] diff --git a/meshroom/nodes/aliceVision/ImageMasking.py b/meshroom/nodes/aliceVision/ImageMasking.py deleted file mode 100644 index e2e1c10b8e..0000000000 --- a/meshroom/nodes/aliceVision/ImageMasking.py +++ /dev/null @@ -1,136 +0,0 @@ -__version__ = "3.0" - -from meshroom.core import desc -from meshroom.core.utils import VERBOSE_LEVEL - - -class ImageMasking(desc.AVCommandLineNode): - commandLine = 'aliceVision_imageMasking {allParams}' - size = desc.DynamicNodeSize('input') - parallelization = desc.Parallelization(blockSize=40) - commandLineRange = '--rangeStart {rangeStart} --rangeSize {rangeBlockSize}' - - documentaiton = ''' - ''' - - inputs = [ - desc.File( - name="input", - label="SfMData", - description="Input SfMData file.", - value="", - ), - desc.ChoiceParam( - name="algorithm", - label="Algorithm", - description="", - value="HSV", - values=["HSV", "AutoGrayscaleThreshold"], - ), - desc.GroupAttribute( - name="hsv", - label="HSV Parameters", - description="Values to select:\n" - " - Green: default values\n" - " - White: Tolerance = 1, minSaturation = 0, maxSaturation = 0.1, minValue = 0.8, maxValue = 1\n" - " - Black: Tolerance = 1, minSaturation = 0, maxSaturation = 0.1, minValue = 0, maxValue = 0.2", - group=None, - enabled=lambda node: node.algorithm.value == "HSV", - groupDesc=[ - desc.FloatParam( - name="hsvHue", - label="Hue", - description="Hue value to isolate in [0,1] range.\n" - "0 = red, 0.33 = green, 0.66 = blue, 1 = red.", - semantic="color/hue", - value=0.33, - range=(0.0, 1.0, 0.01), - ), - desc.FloatParam( - name="hsvHueRange", - label="Tolerance", - description="Tolerance around the hue value to isolate.", - value=0.1, - range=(0.0, 1.0, 0.01), - ), - desc.FloatParam( - name="hsvMinSaturation", - label="Min Saturation", - description="Hue is meaningless if saturation is low. Do not mask pixels below this threshold.", - value=0.3, - range=(0.0, 1.0, 0.01), - ), - desc.FloatParam( - name="hsvMaxSaturation", - label="Max Saturation", - description="Do not mask pixels above this threshold. It might be useful to mask white/black pixels.", - value=1.0, - range=(0.0, 1.0, 0.01), - ), - desc.FloatParam( - name="hsvMinValue", - label="Min Value", - description="Hue is meaningless if the value is low. Do not mask pixels below this threshold.", - value=0.3, - range=(0.0, 1.0, 0.01), - ), - desc.FloatParam( - name="hsvMaxValue", - label="Max Value", - description="Do not mask pixels above this threshold. It might be useful to mask white/black pixels.", - value=1.0, - range=(0.0, 1.0, 0.01), - ), - ], - ), - desc.BoolParam( - name="invert", - label="Invert", - description="If selected, the selected area is ignored.\n" - "If not, only the selected area is considered.", - value=True, - ), - desc.IntParam( - name="growRadius", - label="Grow Radius", - description="Grow the selected area.\n" - "It might be used to fill the holes: then use shrinkRadius to restore the initial coutours.", - value=0, - range=(0, 50, 1), - ), - desc.IntParam( - name="shrinkRadius", - label="Shrink Radius", - description="Shrink the selected area.", - value=0, - range=(0, 50, 1), - ), - desc.File( - name="depthMapFolder", - label="Depth Mask Folder", - description="Depth mask folder.", - value="", - ), - desc.StringParam( - name="depthMapExp", - label="Depth Mask Expression", - description="Depth mask expression, like '{inputFolder}/{stem}-depth.{ext}'.", - value="", - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="output", - label="Output", - description="Output folder.", - value="{nodeCacheFolder}", - ), - ] diff --git a/meshroom/nodes/aliceVision/ImageMatching.py b/meshroom/nodes/aliceVision/ImageMatching.py deleted file mode 100644 index 4fea8330f3..0000000000 --- a/meshroom/nodes/aliceVision/ImageMatching.py +++ /dev/null @@ -1,140 +0,0 @@ -__version__ = "2.0" - -from meshroom.core import desc -from meshroom.core.utils import VERBOSE_LEVEL - - -class ImageMatching(desc.AVCommandLineNode): - commandLine = 'aliceVision_imageMatching {allParams}' - size = desc.DynamicNodeSize('input') - - category = 'Sparse Reconstruction' - documentation = ''' -The goal of this node is to select the image pairs to match. The ambition is to find the images that are looking to the same areas of the scene. -Thanks to this node, the FeatureMatching node will only compute the matches between the selected image pairs. - -It provides multiple methods: - * **VocabularyTree** -It uses image retrieval techniques to find images that share some content without the cost of resolving all feature matches in details. -Each image is represented in a compact image descriptor which allows to compute the distance between all images descriptors very efficiently. -If your scene contains less than "Voc Tree: Minimal Number of Images", all image pairs will be selected. - * **Sequential** -If your input is a video sequence, you can use this option to link images between them over time. - * **SequentialAndVocabularyTree** -Combines sequential approach with Voc Tree to enable connections between keyframes at different times. - * **Exhaustive** -Export all image pairs. - * **Frustum** -If images have known poses, computes the intersection between cameras frustums to create the list of image pairs. - * **FrustumOrVocabularyTree** -If images have known poses, use frustum intersection else use VocabularuTree. - -## Online -[https://alicevision.org/#photogrammetry/image_matching](https://alicevision.org/#photogrammetry/image_matching) -''' - - inputs = [ - desc.File( - name="input", - label="SfMData", - description="Input SfMData file.", - value="", - ), - desc.ListAttribute( - elementDesc=desc.File( - name="featuresFolder", - label="Features Folder", - description="Folder containing some extracted features and descriptors.", - value="", - ), - name="featuresFolders", - label="Features Folders", - description="Folder(s) containing the extracted features and descriptors.", - exposed=True, - ), - desc.ChoiceParam( - name="method", - label="Method", - description="Method used to select the image pairs to match:\n" - " - VocabularyTree: It uses image retrieval techniques to find images that share some content without the cost of resolving all \n" - "feature matches in details. Each image is represented in a compact image descriptor which allows to compute the distance between all \n" - "images descriptors very efficiently. If your scene contains less than 'Voc Tree: Minimal Number of Images', all image pairs will be selected.\n" - " - Sequential: If your input is a video sequence, you can use this option to link images between them over time.\n" - " - SequentialAndVocabularyTree: Combines sequential approach with VocTree to enable connections between keyframes at different times.\n" - " - Exhaustive: Export all image pairs.\n" - " - Frustum: If images have known poses, computes the intersection between cameras frustums to create the list of image pairs.\n" - " - FrustumOrVocabularyTree: If images have known poses, use frustum intersection else use VocabularyTree.\n", - value="SequentialAndVocabularyTree", - values=["VocabularyTree", "Sequential", "SequentialAndVocabularyTree", "Exhaustive", "Frustum", "FrustumOrVocabularyTree"], - ), - desc.File( - name="tree", - label="Voc Tree: Tree", - description="Input name for the vocabulary tree file.", - value="${ALICEVISION_VOCTREE}", - invalidate=False, - enabled=lambda node: "VocabularyTree" in node.method.value, - ), - desc.File( - name="weights", - label="Voc Tree: Weights", - description="Input name for the weight file.\n" - "If not provided, the weights will be computed on the database built with the provided set.", - value="", - advanced=True, - enabled=lambda node: "VocabularyTree" in node.method.value, - ), - desc.IntParam( - name="minNbImages", - label="Voc Tree: Minimum Number Of Images", - description="Minimum number of images to use the vocabulary tree.\n" - "If we have less features than this threshold, we will compute all matching combinations.", - value=200, - range=(0, 500, 1), - advanced=True, - enabled=lambda node: "VocabularyTree" in node.method.value, - ), - desc.IntParam( - name="maxDescriptors", - label="Voc Tree: Max Descriptors", - description="Limit the number of descriptors you load per image. 0 means no limit.", - value=500, - range=(0, 100000, 1), - advanced=True, - enabled=lambda node: "VocabularyTree" in node.method.value, - ), - desc.IntParam( - name="nbMatches", - label="Voc Tree: Nb Matches", - description="The number of matches to retrieve for each image. (If 0, it will retrieve all the matches).", - value=40, - range=(0, 1000, 1), - advanced=True, - enabled=lambda node: "VocabularyTree" in node.method.value, - ), - desc.IntParam( - name="nbNeighbors", - label="Sequential: Nb Neighbors", - description="The number of neighbors to retrieve for each image. (If 0, it will retrieve all the neighbors).", - value=5, - range=(0, 1000, 1), - advanced=True, - enabled=lambda node: "Sequential" in node.method.value, - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="output", - label="Image Pairs", - description="Filepath to the output file with the list of selected image pairs.", - value="{nodeCacheFolder}/imageMatches.txt", - ), - ] diff --git a/meshroom/nodes/aliceVision/ImageMatchingMultiSfM.py b/meshroom/nodes/aliceVision/ImageMatchingMultiSfM.py deleted file mode 100644 index 097bf8a501..0000000000 --- a/meshroom/nodes/aliceVision/ImageMatchingMultiSfM.py +++ /dev/null @@ -1,152 +0,0 @@ -__version__ = "1.0" - -from meshroom.core import desc -from meshroom.core.utils import VERBOSE_LEVEL - - -class ImageMatchingMultiSfM(desc.AVCommandLineNode): - commandLine = 'aliceVision_imageMatching {allParams}' - # use both SfM inputs to define Node's size - size = desc.MultiDynamicNodeSize(['input', 'inputB']) - - category = 'Sparse Reconstruction' - documentation = ''' -The goal of this node is to select the image pairs to match in the context of an SfM augmentation. -The ambition is to find the images that are looking to the same areas of the scene. -Thanks to this node, the FeatureMatching node will only compute the matches between the selected image pairs. - -## Online -[https://alicevision.org/#photogrammetry/image_matching](https://alicevision.org/#photogrammetry/image_matching) -''' - inputs = [ - desc.File( - name="input", - label="Input A", - description="First input SfMData file.", - value="", - ), - desc.File( - name="inputB", - label="Input B", - description="Second input SfMData file.", - value="", - ), - desc.ListAttribute( - elementDesc=desc.File( - name="featuresFolder", - label="Features Folder", - description="Folder containing some extracted features and descriptors.", - value="", - ), - name="featuresFolders", - label="Features Folders", - description="Folder(s) containing the extracted features and descriptors.", - exposed=True, - ), - desc.ChoiceParam( - name="method", - label="Method", - description="Method used to select the image pairs to match:\n" - " - VocabularyTree: It uses image retrieval techniques to find images that share some content " - "without the cost of resolving all \n" - "feature matches in details. Each image is represented in a compact image descriptor which " - "allows to compute the distance between all \n" - "images descriptors very efficiently. If your scene contains less than 'Voc Tree: Minimal " - "Number of Images', all image pairs will be selected.\n" - " - SequentialAndVocabularyTree: Combines sequential approach with VocTree to enable " - "connections between keyframes at different times.\n" - " - Exhaustive: Export all image pairs.\n" - " - Frustum: If images have known poses, computes the intersection between cameras frustums " - "to create the list of image pairs.\n" - " - FrustumOrVocabularyTree: If images have known poses, use frustum intersection. Otherwise, " - "use VocabularyTree.\n", - value="SequentialAndVocabularyTree", - values=["VocabularyTree", "SequentialAndVocabularyTree", "Exhaustive", "Frustum"], - ), - desc.File( - name="tree", - label="Voc Tree: Tree", - description="Input name for the vocabulary tree file.", - value="${ALICEVISION_VOCTREE}", - invalidate=False, - enabled=lambda node: "VocabularyTree" in node.method.value, - ), - desc.File( - name="weights", - label="Voc Tree: Weights", - description="Input name for the weight file.\n" - "If not provided, the weights will be computed on the database built with the provided set.", - value="", - advanced=True, - enabled=lambda node: "VocabularyTree" in node.method.value, - ), - desc.ChoiceParam( - name="matchingMode", - label="Matching Mode", - description="The mode to combine image matching between the input SfMData A and B:\n" - "- 'a/a+a/b' for A with A + A with B.\n" - "- 'a/ab' for A with A and B.\n" - "- 'a/b' for A with B.", - value="a/a+a/b", - values=["a/a+a/b","a/ab", "a/b"], - ), - desc.IntParam( - name="minNbImages", - label="Voc Tree: Minimum Number Of Images", - description="Minimum number of images to use the vocabulary tree.\n" - "If we have less features than this threshold, we will compute all the matching combinations.", - value=200, - range=(0, 500, 1), - advanced=True, - enabled=lambda node: "VocabularyTree" in node.method.value, - ), - desc.IntParam( - name="maxDescriptors", - label="Voc Tree: Max Descriptors", - description="Limit the number of descriptors you load per image. 0 means no limit.", - value=500, - range=(0, 100000, 1), - advanced=True, - enabled=lambda node: "VocabularyTree" in node.method.value, - ), - desc.IntParam( - name="nbMatches", - label="Voc Tree: Nb Matches", - description="The number of matches to retrieve for each image. (If 0, it will retrieve all the matches).", - value=40, - range=(0, 1000, 1), - advanced=True, - enabled=lambda node: "VocabularyTree" in node.method.value, - ), - desc.IntParam( - name="nbNeighbors", - label="Sequential: Nb Neighbors", - description="The number of neighbors to retrieve for each image. (If 0, it will retrieve all the neighbors).", - value=5, - range=(0, 1000, 1), - advanced=True, - enabled=lambda node: "Sequential" in node.method.value, - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="output", - label="List File", - description="Filepath to the output file with the list of selected image pairs.", - value="{nodeCacheFolder}/imageMatches.txt", - ), - desc.File( - name="outputCombinedSfM", - label="Combined SfM", - description="Path for the combined SfMData file.", - value="{nodeCacheFolder}/combineSfM.sfm", - ), - ] diff --git a/meshroom/nodes/aliceVision/ImageProcessing.py b/meshroom/nodes/aliceVision/ImageProcessing.py deleted file mode 100644 index 1aa76d105b..0000000000 --- a/meshroom/nodes/aliceVision/ImageProcessing.py +++ /dev/null @@ -1,628 +0,0 @@ -__version__ = "3.3" - -from meshroom.core import desc -from meshroom.core.utils import COLORSPACES, EXR_STORAGE_DATA_TYPE, RAW_COLOR_INTERPRETATION, VERBOSE_LEVEL - -import os.path - - -def outputImagesValueFunct(attr): - basename = os.path.basename(attr.node.input.value) - fileStem = os.path.splitext(basename)[0] - inputExt = os.path.splitext(basename)[1] - outputExt = ('.' + attr.node.extension.value) if attr.node.extension.value else None - - if inputExt in ['.abc', '.sfm']: - fileStem = '' if attr.node.keepImageFilename.value else '' - # If we have an SfM in input - return "{nodeCacheFolder}/" + fileStem + (outputExt or '.*') - - if inputExt: - # If we have one or multiple files in input - return "{nodeCacheFolder}/" + fileStem + (outputExt or inputExt) - - if '*' in fileStem: - # The fileStem of the input param is a regular expression, - # so even if there is no file extension, - # we consider that the expression represents files. - return "{nodeCacheFolder}/" + fileStem + (outputExt or '.*') - - # No extension and no expression means that the input param is a folder path - return "{nodeCacheFolder}/" + '*' + (outputExt or '.*') - - -class ImageProcessing(desc.AVCommandLineNode): - commandLine = 'aliceVision_imageProcessing {allParams}' - size = desc.DynamicNodeSize('input') - # parallelization = desc.Parallelization(blockSize=40) - # commandLineRange = '--rangeStart {rangeStart} --rangeSize {rangeBlockSize}' - - category = 'Utils' - documentation = ''' -Convert or apply filtering to the input images. -''' - - inputs = [ - desc.File( - name="input", - label="Input", - description="SfMData file input, image filenames or regex(es) on the image file path.\n" - "Supported regex:\n" - " - '#' matches a single digit.\n" - " - '@' matches one or more digits.\n" - " - '?' matches one character.\n" - " - '*' matches zero character or more.", - value="", - ), - desc.ListAttribute( - elementDesc=desc.File( - name="inputFolder", - label="Input Folder", - description="Folder containing images.", - value="", - ), - name="inputFolders", - label="Input Images Folders", - description="Use images from specific folder(s).", - ), - desc.ListAttribute( - elementDesc=desc.StringParam( - name="metadataFolder", - label="Metadata Folder", - description="Specific folder containing images with metadata.", - value="", - ), - name="metadataFolders", - label="Input Metadata Folders", - description="Use images metadata from specific folder(s).", - ), - desc.ChoiceParam( - name="extension", - label="Output File Extension", - description="Output image file extension.\n" - "If unset, the output file extension will match the input's if possible.", - value="", - values=["", "exr", "jpg", "tiff", "png"], - ), - desc.BoolParam( - name="reconstructedViewsOnly", - label="Only Reconstructed Views", - description="Only process reconstructed views.", - value=False, - ), - desc.BoolParam( - name="keepImageFilename", - label="Keep Image Name", - description="Keep the original image name instead of the view name.", - value=False, - ), - desc.BoolParam( - name="reorient", - label="Automatic Reorientation", - description="Automatic image reorientation.", - value=False, - ), - desc.BoolParam( - name="fixNonFinite", - label="Fix Non-Finite", - description="Fix non-finite pixels based on neighboring pixels average.", - value=False, - ), - desc.BoolParam( - name="exposureCompensation", - label="Exposure Compensation", - description="Exposure compensation (only valid for SfMData).", - value=False, - ), - desc.BoolParam( - name="rawAutoBright", - label="RAW Auto Bright", - description="Enable automatic exposure adjustment for RAW images.", - value=False, - ), - desc.FloatParam( - name="rawExposureAdjust", - label="RAW Exposure Adjustment", - description="Manual exposure adjustment in fstops for RAW images.", - value=0.0, - range=(-2.0, 3.0, 0.125), - ), - desc.GroupAttribute( - name="lensCorrection", - label="Lens Correction", - description="Automatic lens correction settings.", - joinChar=":", - groupDesc=[ - desc.BoolParam( - name="lensCorrectionEnabled", - label="Enable", - description="Enable lens correction.", - value=False, - ), - desc.BoolParam( - name="geometry", - label="Geometry", - description="Geometry correction if a model is available in the SfMData.", - value=False, - enabled=lambda node: node.lensCorrection.lensCorrectionEnabled.value, - ), - desc.BoolParam( - name="vignetting", - label="Vignetting", - description="Vignetting correction if the model parameters are available in the metadata.", - value=False, - enabled=lambda node: node.lensCorrection.lensCorrectionEnabled.value, - ), - desc.BoolParam( - name="chromaticAberration", - label="Chromatic Aberration", - description="Chromatic aberration (fringing) correction if the model parameters are available in the metadata.", - value=False, - enabled=lambda node: node.lensCorrection.lensCorrectionEnabled.value, - ), - ], - ), - desc.FloatParam( - name="scaleFactor", - label="Scale Factor", - description="Scale factor.", - value=1.0, - range=(0.0, 1.0, 0.01), - ), - desc.IntParam( - name="maxWidth", - label="Max Width", - description="Maximum width of the output images (0: ignored).", - value=0, - range=(0, 10000, 1), - ), - desc.IntParam( - name="maxHeight", - label="Max Height", - description="Maximum height of the output images (0: ignored).", - value=0, - range=(0, 10000, 1), - ), - desc.FloatParam( - name="contrast", - label="Contrast", - description="Contrast.", - value=1.0, - range=(0.0, 100.0, 0.1), - ), - desc.IntParam( - name="medianFilter", - label="Median Filter", - description="Median filter.", - value=0, - range=(0, 10, 1), - ), - desc.BoolParam( - name="fillHoles", - label="Fill Holes", - description="Fill holes based on the alpha channel.\n" - "Note: It will enable 'fixNonFinite', as it is required for the image pyramid construction used to fill holes.", - value=False, - ), - desc.GroupAttribute( - name="sharpenFilter", - label="Sharpen Filter", - description="Sharpen filter parameters.", - joinChar=":", - groupDesc=[ - desc.BoolParam( - name="sharpenFilterEnabled", - label="Enable", - description="Use sharpen filter.", - value=False, - ), - desc.IntParam( - name="width", - label="Width", - description="Sharpening width.", - value=3, - range=(1, 9, 2), - enabled=lambda node: node.sharpenFilter.sharpenFilterEnabled.value, - ), - desc.FloatParam( - name="contrast", - label="Contrast", - description="Sharpening contrast.", - value=1.0, - range=(0.0, 100.0, 0.1), - enabled=lambda node: node.sharpenFilter.sharpenFilterEnabled.value, - ), - desc.FloatParam( - name="threshold", - label="Threshold", - description="Sharpening threshold.", - value=0.0, - range=(0.0, 1.0, 0.01), - enabled=lambda node: node.sharpenFilter.sharpenFilterEnabled.value, - ), - ], - ), - desc.GroupAttribute( - name="bilateralFilter", - label="Bilateral Filter", - description="Bilateral filter parameters.", - joinChar=":", - groupDesc=[ - desc.BoolParam( - name="bilateralFilterEnabled", - label="Enable", - description="Use bilateral filter.", - value=False, - ), - desc.IntParam( - name="bilateralFilterDistance", - label="Distance", - description="Diameter of each pixel neighborhood that is used during bilateral filtering.\n" - "Could be very slow for large filters, so it is recommended to use 5.", - value=0, - range=(0, 9, 1), - enabled=lambda node: node.bilateralFilter.bilateralFilterEnabled.value, - ), - desc.FloatParam( - name="bilateralFilterSigmaSpace", - label="Sigma Coordinate Space", - description="Bilateral filter sigma in the coordinate space.", - value=0.0, - range=(0.0, 150.0, 0.01), - enabled=lambda node: node.bilateralFilter.bilateralFilterEnabled.value, - ), - desc.FloatParam( - name="bilateralFilterSigmaColor", - label="Sigma Color Space", - description="Bilateral filter sigma in the color space.", - value=0.0, - range=(0.0, 150.0, 0.01), - enabled=lambda node: node.bilateralFilter.bilateralFilterEnabled.value, - ), - ], - ), - desc.GroupAttribute( - name="claheFilter", - label="Clahe Filter", - description="Clahe filter parameters.", - joinChar=":", - groupDesc=[ - desc.BoolParam( - name="claheEnabled", - label="Enable", - description="Use Contrast Limited Adaptive Histogram Equalization (CLAHE) filter.", - value=False, - ), - desc.FloatParam( - name="claheClipLimit", - label="Clip Limit", - description="Threshold for contrast limiting.", - value=4.0, - range=(0.0, 8.0, 1.0), - enabled=lambda node: node.claheFilter.claheEnabled.value, - ), - desc.IntParam( - name="claheTileGridSize", - label="Tile Grid Size", - description="Size of the grid for histogram equalization.\n" - "Input image will be divided into equally sized rectangular tiles.", - value=8, - range=(4, 64, 4), - enabled=lambda node: node.claheFilter.claheEnabled.value, - ), - ], - ), - desc.GroupAttribute( - name="noiseFilter", - label="Noise Filter", - description="Noise filter parameters.", - joinChar=":", - groupDesc=[ - desc.BoolParam( - name="noiseEnabled", - label="Enable", - description="Add noise.", - value=False, - ), - desc.ChoiceParam( - name="noiseMethod", - label="Method", - description="There are several noise types to choose from:\n" - " - uniform: adds noise values uniformly distributed on range [A,B).\n" - " - gaussian: adds Gaussian (normal distribution) noise values with mean value A and standard deviation B.\n" - " - salt: changes to value A a portion of pixels given by B.\n", - value="uniform", - values=["uniform", "gaussian", "salt"], - enabled=lambda node: node.noiseFilter.noiseEnabled.value, - ), - desc.FloatParam( - name="noiseA", - label="A", - description="Parameter that has a different interpretation depending on the chosen method:\n" - " - uniform: lower bound of the range on which the noise is uniformly distributed.\n" - " - gaussian: the mean value of the Gaussian noise.\n" - " - salt: the value of the specified portion of pixels.", - value=0.0, - range=(0.0, 1.0, 0.0001), - enabled=lambda node: node.noiseFilter.noiseEnabled.value, - ), - desc.FloatParam( - name="noiseB", - label="B", - description="Parameter that has a different interpretation depending on the chosen method:\n" - " - uniform: higher bound of the range on which the noise is uniformly distributed.\n" - " - gaussian: the standard deviation of the Gaussian noise.\n" - " - salt: the portion of pixels to set to a specified value.", - value=1.0, - range=(0.0, 1.0, 0.0001), - enabled=lambda node: node.noiseFilter.noiseEnabled.value, - ), - desc.BoolParam( - name="noiseMono", - label="Mono", - description="If selected, a single noise value will be applied to all channels.\n" - "Otherwise, a separate noise value will be computed for each channel.", - value=True, - enabled=lambda node: node.noiseFilter.noiseEnabled.value, - ), - ], - ), - desc.GroupAttribute( - name="nlmFilter", - label="NL Means Denoising (8 bits)", - description="NL Means Denoising Parameters.\n" - "This implementation only works on 8-bit images, so the colors can be reduced and clamped.", - joinChar=":", - groupDesc=[ - desc.BoolParam( - name="nlmFilterEnabled", - label="Enable", - description="Use Non-Local Mean Denoising from OpenCV to denoise images.", - value=False, - ), - desc.FloatParam( - name="nlmFilterH", - label="H", - description="Parameter regulating the filter strength for the luminance component.\n" - "Bigger H value perfectly removes noise but also removes image details,\n" - "smaller H value preserves details but also preserves some noise.", - value=5.0, - range=(1.0, 1000.0, 0.01), - enabled=lambda node: node.nlmFilter.nlmFilterEnabled.value, - ), - desc.FloatParam( - name="nlmFilterHColor", - label="HColor", - description="Parameter regulating filter strength for color components. Not necessary for grayscale images.\n" - "Bigger HColor value perfectly removes noise but also removes image details,\n" - "smaller HColor value preserves details but also preserves some noise.", - value=10.0, - range=(0.0, 1000.0, 0.01), - enabled=lambda node: node.nlmFilter.nlmFilterEnabled.value, - ), - desc.IntParam( - name="nlmFilterTemplateWindowSize", - label="Template Window Size", - description="Size in pixels of the template patch that is used to compute weights. Should be odd.", - value=7, - range=(1, 101, 2), - enabled=lambda node: node.nlmFilter.nlmFilterEnabled.value, - ), - desc.IntParam( - name="nlmFilterSearchWindowSize", - label="Search Window Size", - description="Size in pixels of the window that is used to compute weighted average for a given pixel.\n" - "Should be odd. Affect performance linearly: greater searchWindowsSize - greater denoising time.", - value=21, - range=(1, 1001, 2), - enabled=lambda node: node.nlmFilter.nlmFilterEnabled.value, - ), - ], - ), - desc.GroupAttribute( - name="parFilter", - label="Pixel Aspect Ratio", - description="Pixel Aspect Ratio parameters.", - joinChar=":", - groupDesc=[ - desc.BoolParam( - name="parEnabled", - label="Enable", - description="Apply pixel aspect ratio.", - value=False, - ), - desc.BoolParam( - name="parRowDecimation", - label="Row decimation", - description="If selected, reduce image height by decimating the number of rows.\n" - "Otherwise, increase width by upsampling image columns.", - value=False, - enabled=lambda node: node.parFilter.parEnabled.value, - ), - ], - ), - desc.ChoiceParam( - name="outputFormat", - label="Output Image Format", - description="Allows you to choose the format of the output image.", - value="rgba", - values=["rgba", "rgb", "grayscale"], - ), - desc.ChoiceParam( - name="inputColorSpace", - label="Input Color Space", - description="Allows you to force the color space of the input image.", - values=COLORSPACES, - value="AUTO", - ), - desc.ChoiceParam( - name="outputColorSpace", - label="Output Color Space", - description="Allows you to choose the color space of the output image.", - values=COLORSPACES, - value="AUTO", - ), - desc.ChoiceParam( - name="workingColorSpace", - label="Working Color Space", - description="Allows you to choose the color space in which the data are processed.", - values=COLORSPACES, - value="Linear", - enabled=lambda node: not node.applyDcpMetadata.value, - ), - desc.ChoiceParam( - name="rawColorInterpretation", - label="RAW Color Interpretation", - description="Allows you to choose how RAW data are color processed.", - values=RAW_COLOR_INTERPRETATION, - value="DCPLinearProcessing" if os.environ.get("ALICEVISION_COLOR_PROFILE_DB", "") else "LibRawWhiteBalancing", - ), - desc.BoolParam( - name="applyDcpMetadata", - label="Apply DCP Metadata", - description="If the image contains some DCP metadata, then generate a DCP profile from them and apply it to the image content.", - value=False, - ), - desc.File( - name="colorProfileDatabase", - label="Color Profile Database", - description="Color profile database directory path.", - value="${ALICEVISION_COLOR_PROFILE_DB}", - invalidate=False, - enabled=lambda node: (node.rawColorInterpretation.value == "DCPLinearProcessing") or (node.rawColorInterpretation.value == "DCPMetadata"), - ), - desc.BoolParam( - name="errorOnMissingColorProfile", - label="Error On Missing DCP Color Profile", - description="If a color profile database is specified but no color profile is found for at least one image, then an error is thrown.", - value=True, - enabled=lambda node: (node.rawColorInterpretation.value == "DCPLinearProcessing") or (node.rawColorInterpretation.value == "DCPMetadata"), - ), - desc.BoolParam( - name="useDCPColorMatrixOnly", - label="Use DCP Color Matrix Only", - description="Use only the Color Matrix information from the DCP and ignore the Forward Matrix.", - value=True, - enabled=lambda node: (node.rawColorInterpretation.value == "DCPLinearProcessing") or (node.rawColorInterpretation.value == "DCPMetadata"), - ), - desc.BoolParam( - name="doWBAfterDemosaicing", - label="WB After Demosaicing", - description="Do White Balance after demosaicing, just before DCP profile application.", - value=False, - enabled=lambda node: (node.rawColorInterpretation.value == "DCPLinearProcessing") or (node.rawColorInterpretation.value == "DCPMetadata"), - ), - desc.ChoiceParam( - name="demosaicingAlgo", - label="Demosaicing Algorithm", - description="LibRaw demosaicing algorithm to use.", - value="AHD", - values=["linear", "VNG", "PPG", "AHD", "DCB", "AHD-Mod", "AFD", "VCD", "Mixed", "LMMSE", "AMaZE", "DHT", "AAHD", "none"], - ), - desc.ChoiceParam( - name="highlightMode", - label="Highlight Mode", - description="LibRaw highlight mode:\n" - " - 0: Clip (default)\n" - " - 1: Unclip\n" - " - 2: Blend\n" - " - 3-9: Rebuild", - value=0, - values=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9], - ), - desc.FloatParam( - name="correlatedColorTemperature", - label="Illuminant Color Temperature", - description="Scene illuminant color temperature in Kelvin.\n" - "A negative or null value indicates that the metadata information will be used.", - value=-1.0, - range=(-1.0, 10000.0, 1.0), - ), - desc.File( - name="lensCorrectionProfileInfo", - label="Lens Correction Profile Info", - description="Lens Correction Profile filepath or database directory.", - value="${ALICEVISION_LENS_PROFILE_INFO}", - invalidate=False, - ), - desc.BoolParam( - name="lensCorrectionProfileSearchIgnoreCameraModel", - label="LCP Generic Search", - description="The lens name and camera maker are used to match the LCP database, but the camera model is ignored.", - value=True, - advanced=True, - ), - desc.ChoiceParam( - name="storageDataType", - label="Storage Data Type For EXR Output", - description="Storage image data type for EXR outputs:\n" - " - float: Use full floating point (32 bits per channel).\n" - " - half: Use half float (16 bits per channel).\n" - " - halfFinite: Use half float, but clamp values to avoid non-finite values.\n" - " - auto: Use half float if all values can fit, else use full float.", - values=EXR_STORAGE_DATA_TYPE, - value="float", - ), - desc.ChoiceParam( - name="exrCompressionMethod", - label="EXR Compression Method", - description="Compression method for EXR output images.", - value="auto", - values=["none", "auto", "rle", "zip", "zips", "piz", "pxr24", "b44", "b44a", "dwaa", "dwab"], - ), - desc.IntParam( - name="exrCompressionLevel", - label="EXR Compression Level", - description="Level of compression for EXR images. The range depends on the used method.\n" - "For the zip/zips methods, values must be between 1 and 9.\n" - "A value of 0 will be ignored, and the default value for the selected method will be used.", - value=0, - range=(0, 500, 1), - enabled=lambda node: node.exrCompressionMethod.value in ["dwaa", "dwab", "zip", "zips"], - ), - desc.BoolParam( - name="jpegCompress", - label="JPEG Compress", - description="Enable JPEG compression.", - value=True, - ), - desc.IntParam( - name="jpegQuality", - label="JPEG Quality", - description="JPEG images quality after compression.", - value=90, - range=(0, 100, 1), - enabled=lambda node: node.jpegCompress.value, - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="outSfMData", - label="SfMData", - description="Output SfMData file.", - value=lambda attr: ("{nodeCacheFolder}/" + os.path.basename(attr.node.input.value)) if (os.path.splitext(attr.node.input.value)[1] in [".abc", ".sfm"]) else "", - group="", # do not export on the command line - ), - desc.File( - name="output", - label="Folder", - description="Output images folder.", - value="{nodeCacheFolder}", - ), - desc.File( - name="outputImages", - label="Images", - description="Output images.", - semantic="image", - value=outputImagesValueFunct, - group="", # do not export on the command line - ), - ] diff --git a/meshroom/nodes/aliceVision/ImageSegmentation.py b/meshroom/nodes/aliceVision/ImageSegmentation.py deleted file mode 100644 index 889d931d8d..0000000000 --- a/meshroom/nodes/aliceVision/ImageSegmentation.py +++ /dev/null @@ -1,94 +0,0 @@ -__version__ = "1.2" - -from meshroom.core import desc -from meshroom.core.utils import VERBOSE_LEVEL - - -class ImageSegmentation(desc.AVCommandLineNode): - commandLine = 'aliceVision_imageSegmentation {allParams}' - size = desc.DynamicNodeSize('input') - gpu = desc.Level.INTENSIVE - parallelization = desc.Parallelization(blockSize=50) - commandLineRange = '--rangeStart {rangeStart} --rangeSize {rangeBlockSize}' - - category = 'Utils' - documentation = ''' -Generate a mask with segmented labels for each pixel. -''' - - inputs = [ - desc.File( - name="input", - label="Input", - description="SfMData file input.", - value="", - ), - desc.File( - name="modelPath", - label="Segmentation Model", - description="Weights file for the internal model.", - value="${ALICEVISION_SEMANTIC_SEGMENTATION_MODEL}", - ), - desc.ChoiceParam( - name="validClasses", - label="Classes", - description="Classes names which are to be considered.", - value=["person"], - values=[ - "__background__", - "aeroplane", - "bicycle", "bird", "boat", "bottle", "bus", - "car", "cat", "chair", "cow", - "diningtable", "dog", - "horse", - "motorbike", - "person", "pottedplant", - "sheep", "sofa", - "train", "tvmonitor" - ], - exclusive=False, - ), - desc.BoolParam( - name="maskInvert", - label="Invert Masks", - description="Invert mask values. If selected, the pixels corresponding to the mask will be set to 0 instead of 255.", - value=False, - ), - desc.BoolParam( - name="useGpu", - label="Use GPU", - description="Use GPU for computation if available", - value=True, - invalidate=False, - ), - desc.BoolParam( - name="keepFilename", - label="Keep Filename", - description="Keep Input Filename", - value=False, - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="output", - label="Masks Folder", - description="Output path for the masks.", - value="{nodeCacheFolder}", - ), - desc.File( - name="masks", - label="Masks", - description="Generated segmentation masks.", - semantic="image", - value=lambda attr: "{nodeCacheFolder}/.exr" if not attr.node.keepFilename.value else "{nodeCacheFolder}/.exr", - group="", - ), - ] diff --git a/meshroom/nodes/aliceVision/ImportE57.py b/meshroom/nodes/aliceVision/ImportE57.py deleted file mode 100644 index ef1ac204ff..0000000000 --- a/meshroom/nodes/aliceVision/ImportE57.py +++ /dev/null @@ -1,65 +0,0 @@ -__version__ = "1.0" - -from meshroom.core import desc -from meshroom.core.utils import VERBOSE_LEVEL - - -class ImportE57(desc.AVCommandLineNode): - commandLine = 'aliceVision_importE57 {allParams}' - size = desc.DynamicNodeSize('input') - - category = 'Utils' - documentation = ''' -Import an E57 file and generate an SfMData. -''' - - inputs = [ - desc.ListAttribute( - elementDesc=desc.File( - name="inputFile", - label="E57 File", - description="Path to an E57 file.", - value="", - ), - name="input", - label="Input Files", - description="Set of E57 files in the same reference frame.", - ), - desc.FloatParam( - name="maxDensity", - label="Points Density", - description="Ensure each point has no neighbour closer than maxDensity meters.", - value=0.01, - range=(0.0, 0.2, 0.001), - ), - desc.FloatParam( - name="minIntensity", - label="Laser Intensity Lower Limit", - description="Ensure no point has an intensity lower than this value.", - value=0.03, - range=(0.0, 1.0, 0.01), - ), - desc.IntParam( - name="maxPointsPerBlock", - label="Points Limit", - description="Limit the number of points per computation region (For memory usage, 0 means no limit).", - value=5000000, - range=(0, 10000000, 100000), - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="output", - label="Output", - description="Path to the output JSON file.", - value="{nodeCacheFolder}/inputset.json", - ), - ] diff --git a/meshroom/nodes/aliceVision/ImportKnownPoses.py b/meshroom/nodes/aliceVision/ImportKnownPoses.py deleted file mode 100644 index 0a7e5e9866..0000000000 --- a/meshroom/nodes/aliceVision/ImportKnownPoses.py +++ /dev/null @@ -1,44 +0,0 @@ -__version__ = "1.0" - -from meshroom.core import desc -from meshroom.core.utils import VERBOSE_LEVEL - - -class ImportKnownPoses(desc.AVCommandLineNode): - commandLine = 'aliceVision_importKnownPoses {allParams}' - size = desc.DynamicNodeSize('sfmData') - - documentation = ''' - Import known poses from various file formats like xmp or json. - ''' - - inputs = [ - desc.File( - name="sfmData", - label="SfMData", - description="Input SfMData file.", - value="", - ), - desc.File( - name="knownPosesData", - label="Known Poses Data", - description="Known poses data in the JSON or XMP format.", - value="", - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="output", - label="Output", - description="Path to the output SfMData file.", - value="{nodeCacheFolder}/sfmData.abc", - ), - ] diff --git a/meshroom/nodes/aliceVision/IntrinsicsTransforming.py b/meshroom/nodes/aliceVision/IntrinsicsTransforming.py deleted file mode 100644 index 223851afbb..0000000000 --- a/meshroom/nodes/aliceVision/IntrinsicsTransforming.py +++ /dev/null @@ -1,67 +0,0 @@ -__version__ = "1.0" - -from meshroom.core import desc -from meshroom.core.utils import VERBOSE_LEVEL - -class IntrinsicsTransforming(desc.AVCommandLineNode): - commandLine = 'aliceVision_intrinsicsTransforming {allParams}' - size = desc.DynamicNodeSize('input') - - category = 'Utils' - documentation = ''' - Transforms all intrinsics in the sfmData to a new type. - ''' - - inputs = [ - desc.File( - name="input", - label="Input SfMData", - description="Input SfMData file.", - value="", - ), - desc.File( - name="inputTracks", - label="Input Tracks", - description="Input Tracks file.", - value="", - ), - desc.ChoiceParam( - name="type", - label="Camera Type", - description="Mathematical model used to represent a camera:\n" - " - pinhole: Simplest projective camera model without optical distortion " - "(focal and optical center).\n" - " - equirectangular: Projection model used in panoramas.\n", - value="pinhole", - values=["pinhole", "equidistant", "equirectangular"], - ), - desc.FloatParam( - name="fakeFov", - label="Virtual FOV", - description="If the input intrinsic is not a pinhole but the output is, what is the virtual FOV requested.", - value=90.0, - range=(1.0, 179.0, 0.1), - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="output", - label="Output SfMData", - description="Output SfMData file.", - value="{nodeCacheFolder}/sfmData.abc", - ), - desc.File( - name="outputTracks", - label="Output Tracks", - description="Output Tracks file.", - value="{nodeCacheFolder}/tracksFile.json", - ), - ] diff --git a/meshroom/nodes/aliceVision/KeyframeSelection.py b/meshroom/nodes/aliceVision/KeyframeSelection.py deleted file mode 100644 index 6fb405774d..0000000000 --- a/meshroom/nodes/aliceVision/KeyframeSelection.py +++ /dev/null @@ -1,409 +0,0 @@ -__version__ = "5.0" - -from meshroom.core import desc -from meshroom.core.utils import EXR_STORAGE_DATA_TYPE, VERBOSE_LEVEL - -# List of supported video extensions (provided by OpenImageIO) -videoExts = [".avi", ".mov", ".mp4", ".m4a", ".m4v", ".3gp", ".3g2", ".mj2", ".m4v", ".mpg"] - -class KeyframeSelectionNodeSize(desc.DynamicNodeSize): - def computeSize(self, node): - inputPathsSize = super(KeyframeSelectionNodeSize, self).computeSize(node) - s = 0 - finalSize = 0 - defaultParam = self._param - - # Compute the size for each entry in the list of input paths - for input in node.attribute("inputPaths").value: - self._param = input.getFullName() - s = s + super(KeyframeSelectionNodeSize, self).computeSize(node) - - # Retrieve the maximum number of keyframes for the smart selection (which is high by default) - maxFramesSmart = node.attribute("selectionMethod.smartSelection.maxNbOutFrames").value - - # If the smart selection is enabled and the number of input frames is available (s is not equal to the number of input paths), - # set the size as the minimum between the number of input frames and maximum number of output keyframes. If the number of - # input frames is not available, set the size to the maximum number of output keyframes. - smartSelectionOn = node.attribute("selectionMethod.useSmartSelection").value - if smartSelectionOn: - if s != inputPathsSize: - finalSize = min(s, maxFramesSmart) - else: - finalSize = maxFramesSmart - - # If the smart selection is not enabled, the maximum number of output keyframes for the regular mode can be used - # if and only if it has been set, in the same way as for the smart selection. If the maximum number of frames has - # not been set, then the size is either the minimum between the maximum number of output keyframes for the smart - # selection and the number of input frames if it is available, or the maximum number of output keyframes for the - # smart selection if the number of input frames is not available. - else: - maxFrames = node.attribute("selectionMethod.regularSelection.maxNbOutFrames").value - if maxFrames > 0 and s != inputPathsSize: - finalSize = min(s, maxFrames) - elif maxFrames > 0 and s == inputPathsSize: - finalSize = maxFrames - elif maxFrames <= 0 and s != inputPathsSize: - finalSize = min(s, maxFramesSmart) - else: - finalSize = maxFramesSmart - - # Reset the param used to compute size to the default one: if the size is computed again, - # this will prevent having an inputPathsSize that is erroneous - self._param = defaultParam - return finalSize - - -class KeyframeSelection(desc.AVCommandLineNode): - commandLine = 'aliceVision_keyframeSelection {allParams}' - size = KeyframeSelectionNodeSize('inputPaths') - - category = 'Utils' - documentation = ''' -Allows to extract keyframes from a video and insert metadata. -It can extract frames from a synchronized multi-cameras rig. - -You can extract frames at regular interval by configuring only the min/maxFrameStep. -''' - - inputs = [ - desc.ListAttribute( - elementDesc=desc.File( - name="inputPath", - label="Input Path", - description="Input path.", - value="", - ), - name="inputPaths", - label="Input Paths", - description="Input video files, image sequence directories or SfMData file.", - ), - desc.ListAttribute( - elementDesc=desc.File( - name="brand", - label="Brand", - description="Camera brand.", - value="", - ), - name="brands", - label="Brands", - description="Camera brands.", - ), - desc.ListAttribute( - elementDesc=desc.File( - name="model", - label="Model", - description="Camera model.", - value="", - ), - name="models", - label="Models", - description="Camera models.", - ), - desc.ListAttribute( - elementDesc=desc.FloatParam( - name="mmFocal", - label="Focal", - description="Focal in mm (will be used if not 0).", - value=0.0, - range=(0.0, 500.0, 1.0), - ), - name="mmFocals", - label="Focals", - description="Focals in mm (will be used if not 0).", - ), - desc.File( - name="sensorDbPath", - label="Sensor Database", - description="Camera sensor width database path.", - value="${ALICEVISION_SENSOR_DB}", - ), - desc.ListAttribute( - elementDesc=desc.File( - name="masks", - label="Masks Path", - description="Directory containing masks to apply to the frames.", - value="", - ), - name="maskPaths", - label="Masks", - description="Masks (e.g. segmentation masks) used to exclude some parts of the frames from the score computations\n" - "for the smart keyframe selection.", - enabled=lambda node: node.selectionMethod.useSmartSelection.value, - ), - desc.GroupAttribute( - name="selectionMethod", - label="Keyframe Selection Method", - description="Selection the regular or smart method for the keyframe selection.\n" - "- With the regular method, keyframes are selected regularly over the sequence with respect to the set parameters.\n" - "- With the smart method, keyframes are selected based on their sharpness and optical flow scores.", - group=None, # skip group from command line - groupDesc=[ - desc.BoolParam( - name="useSmartSelection", - label="Use Smart Keyframe Selection", - description="Use the smart keyframe selection.", - value=True, - ), - desc.GroupAttribute( - name="regularSelection", - label="Regular Keyframe Selection", - description="Parameters for the regular keyframe selection.\n" - "Keyframes are selected regularly over the sequence with respect to the set parameters.", - group=None, # skip group from command line - enabled=lambda node: node.selectionMethod.useSmartSelection.value is False, - groupDesc=[ - desc.IntParam( - name="minFrameStep", - label="Min Frame Step", - description="Minimum number of frames between two keyframes.", - value=12, - range=(1, 1000, 1), - enabled=lambda node: node.regularSelection.enabled, - ), - desc.IntParam( - name="maxFrameStep", - label="Max Frame Step", - description="Maximum number of frames between two keyframes. Ignored if equal to 0.", - value=0, - range=(0, 1000, 1), - enabled=lambda node: node.regularSelection.enabled, - ), - desc.IntParam( - name="maxNbOutFrames", - label="Max Nb Output Frames", - description="Maximum number of output frames (0 = no limit).\n" - "'minFrameStep' and 'maxFrameStep' will always be respected, so combining them with this parameter\n" - "might cause the selection to stop before reaching the end of the input sequence(s).", - value=0, - range=(0, 10000, 1), - enabled=lambda node: node.regularSelection.enabled, - ), - ], - ), - desc.GroupAttribute( - name="smartSelection", - label="Smart Keyframe Selection", - description="Parameters for the smart keyframe selection.\n" - "Keyframes are selected based on their sharpness and optical flow scores.", - group=None, # skip group from command line - enabled=lambda node: node.selectionMethod.useSmartSelection.value, - groupDesc=[ - desc.FloatParam( - name="pxDisplacement", - label="Pixel Displacement", - description="The percentage of pixels in the frame that need to have moved since the last keyframe to be considered for the selection.", - value=10.0, - range=(0.0, 100.0, 1.0), - enabled=lambda node: node.smartSelection.enabled, - ), - desc.IntParam( - name="minNbOutFrames", - label="Min Nb Output Frames", - description="Minimum number of frames selected to be keyframes.", - value=40, - range=(1, 100, 1), - enabled=lambda node: node.smartSelection.enabled, - ), - desc.IntParam( - name="maxNbOutFrames", - label="Max Nb Output Frames", - description="Maximum number of frames selected to be keyframes.", - value=2000, - range=(1, 10000, 1), - enabled=lambda node: node.smartSelection.enabled, - ), - desc.IntParam( - name="rescaledWidthSharpness", - label="Rescaled Frame's Width For Sharpness", - description="Width, in pixels, of the frame used for the sharpness score computation after a rescale.\n" - "Aspect ratio will be preserved. No rescale will be performed if equal to 0.", - value=720, - range=(0, 4000, 1), - enabled=lambda node: node.smartSelection.enabled, - advanced=True, - ), - desc.IntParam( - name="rescaledWidthFlow", - label="Rescaled Frame's Width For Motion", - description="Width, in pixels, of the frame used for the motion score computation after a rescale.\n" - "Aspect ratio will be preserved. No rescale will be performed if equal to 0.", - value=720, - range=(0, 4000, 1), - enabled=lambda node: node.smartSelection.enabled, - advanced=True, - ), - desc.IntParam( - name="sharpnessWindowSize", - label="Sharpness Window Size", - description="The size, in pixels, of the sliding window used to evaluate a frame's sharpness.", - value=200, - range=(1, 10000, 1), - enabled=lambda node: node.smartSelection.enabled, - advanced=True, - ), - desc.IntParam( - name="flowCellSize", - label="Optical Flow Cell Size", - description="The size, in pixels, of the cells within a frame in which the optical flow scores is evaluated.", - value=90, - range=(10, 2000, 1), - enabled=lambda node: node.smartSelection.enabled, - advanced=True, - ), - desc.IntParam( - name="minBlockSize", - label="Multi-Threading Minimum Block Size", - description="The minimum number of frames to process for a thread to be spawned.\n" - "If using all the available threads implies processing less than this value in every thread, then less threads should be spawned,\n" - "and each will process at least 'minBlockSize' (except maybe for the very last thread, that might process less).", - value=10, - range=(1, 1000, 1), - invalidate=False, - enabled=lambda node: node.smartSelection.enabled, - advanced=True, - ), - ], - ), - ], - ), - desc.BoolParam( - name="renameKeyframes", - label="Rename Output Keyframes", - description="Instead of using the selected keyframes' index as their name, name them as consecutive output frames.\n" - "If the selected keyframes are at index [15, 294, 825], they will be written as [00000.exr, 00001.exr, 00002.exr] with this\n" - "option enabled instead of [00015.exr, 00294.exr, 00825.exr].", - value=False, - enabled=lambda node: node.outputExtension.value != "none", - ), - desc.ChoiceParam( - name="outputExtension", - label="Keyframes File Extension", - description="File extension of the written keyframes.\n" - "If 'none' is selected, no keyframe will be written on disk.\n" - "For input videos, 'none' should not be used since the written keyframes are used to generate the output SfMData file.", - value="none", - values=["none", "exr", "jpg", "png"], - validValue=lambda node: not (any(ext in input.value.lower() for ext in videoExts for input in node.inputPaths.value) and node.outputExtension.value == "none"), - errorMessage="A video input has been provided. The output extension should be different from 'none'.", - ), - desc.ChoiceParam( - name="storageDataType", - label="EXR Storage Data Type", - description="Storage image data type for keyframes written to EXR files:\n" - " - float: Use full floating point (32 bits per channel).\n" - " - half: Use half float (16 bits per channel).\n" - " - halfFinite: Use half float, but clamp values to avoid non-finite values.\n" - " - auto: Use half float if all values can fit, else use full float.", - values=EXR_STORAGE_DATA_TYPE, - value="float", - enabled=lambda node: node.outputExtension.value == "exr", - advanced=True, - ), - desc.GroupAttribute( - name="debugOptions", - label="Debug Options", - description="Debug options for the Smart keyframe selection method.", - group=None, # skip group from command line - enabled=lambda node: node.selectionMethod.useSmartSelection.value, - advanced=True, - groupDesc=[ - desc.GroupAttribute( - name="debugScores", - label="Export Scores", - description="Export the computed sharpness and optical flow scores to a file.", - group=None, # skip group from command line - enabled=lambda node: node.debugOptions.enabled, - groupDesc=[ - desc.BoolParam( - name="exportScores", - label="Export Scores To CSV", - description="Export the computed sharpness and optical flow scores to a CSV file.", - value=False, - ), - desc.StringParam( - name="csvFilename", - label="CSV Filename", - description="Name of the CSV file to export. It will be written in the node's output folder.", - value="scores.csv", - enabled=lambda node: node.debugOptions.debugScores.exportScores.value, - ), - desc.BoolParam( - name="exportSelectedFrames", - label="Export Selected Frames", - description="Add a column in the CSV file containing 1s for frames that were selected and 0s for those that were not.", - value=False, - enabled=lambda node: node.debugOptions.debugScores.exportScores.value, - ), - ], - ), - desc.GroupAttribute( - name="opticalFlowVisualisation", - label="Optical Flow Visualisation", - description="Visualise the motion vectors for each input frame in HSV.", - group=None, # skip group from command line - enabled=lambda node: node.debugOptions.enabled, - groupDesc=[ - desc.BoolParam( - name="exportFlowVisualisation", - label="Visualise Optical Flow", - description="Export each frame's optical flow HSV visualisation as PNG images.", - value=False, - enabled=lambda node: node.debugOptions.opticalFlowVisualisation.enabled, - ), - desc.BoolParam( - name="flowVisualisationOnly", - label="Only Visualise Optical Flow", - description="Export each frame's optical flow HSV visualisation as PNG images, but do not perform any score computation or frame selection.\n" - "If this option is selected, all the other options will be ignored.", - value=False, - enabled=lambda node: node.debugOptions.opticalFlowVisualisation.enabled, - ), - ], - ), - desc.BoolParam( - name="skipSharpnessComputation", - label="Skip Sharpness Computation", - description="Skip the sharpness score computation. A fixed score of 1.0 will be applied by default to all the frames.", - value=False, - enabled=lambda node: node.debugOptions.enabled, - ), - desc.BoolParam( - name="skipSelection", - label="Skip Frame Selection", - description="Compute the sharpness and optical flow scores, but do not proceed to the frame selection.", - value=False, - enabled=lambda node: node.debugOptions.enabled, - ), - ], - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="outputFolder", - label="Folder", - description="Output keyframes folder for extracted frames.", - value="{nodeCacheFolder}", - ), - desc.File( - name="outputSfMDataKeyframes", - label="Keyframes SfMData", - description="Output SfMData file containing all the selected keyframes.", - value="{nodeCacheFolder}/keyframes.sfm", - ), - desc.File( - name="outputSfMDataFrames", - label="Frames SfMData", - description="Output SfMData file containing all the frames that were not selected as keyframes.\n" - "If the input contains videos, this file will not be written since all the frames that were not selected do not actually exist on disk.", - value="{nodeCacheFolder}/frames.sfm", - ), - ] - diff --git a/meshroom/nodes/aliceVision/LdrToHdrCalibration.py b/meshroom/nodes/aliceVision/LdrToHdrCalibration.py deleted file mode 100644 index 30002ebe97..0000000000 --- a/meshroom/nodes/aliceVision/LdrToHdrCalibration.py +++ /dev/null @@ -1,254 +0,0 @@ -__version__ = "3.1" - -import json - -from meshroom.core import desc -from meshroom.core.utils import COLORSPACES, VERBOSE_LEVEL - -def findMetadata(d, keys, defaultValue): - v = None - for key in keys: - v = d.get(key, None) - k = key.lower() - if v is not None: - return v - for dk, dv in d.items(): - 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.AVCommandLineNode): - commandLine = 'aliceVision_LdrToHdrCalibration {allParams}' - size = desc.DynamicNodeSize('input') - cpu = desc.Level.INTENSIVE - ram = desc.Level.NORMAL - - category = 'Panorama HDR' - documentation = ''' -Calibrate LDR to HDR response curve from samples. -''' - - inputs = [ - desc.File( - name="input", - label="SfMData", - description="Input SfMData file.", - value="", - ), - desc.File( - name="samples", - label="Samples Folder", - description="Samples folder.", - value="{nodeCacheFolder}", - ), - desc.IntParam( - name="userNbBrackets", - label="Number Of Brackets", - description="Number of exposure brackets per HDR image (0 for automatic detection).", - value=0, - range=(0, 15, 1), - invalidate=False, - group="user", # not used directly on the command line - errorMessage="The set number of brackets is not a multiple of the number of input images.\n" - "Errors will occur during the computation.", - exposed=True, - ), - desc.IntParam( - name="nbBrackets", - label="Automatic Nb Brackets", - description="Number of exposure brackets used per HDR image.\n" - "It is detected automatically from input Viewpoints metadata if 'userNbBrackets' is 0,\n" - "else it is equal to 'userNbBrackets'.", - value=0, - range=(0, 15, 1), - group="bracketsParams", - ), - desc.BoolParam( - name="byPass", - label="Bypass", - description="Bypass HDR creation and use the medium bracket as the source for the next steps.", - value=False, - enabled=lambda node: node.nbBrackets.value != 1, - exposed=True, - ), - desc.ChoiceParam( - name="calibrationMethod", - label="Calibration Method", - description="Method used for camera calibration:\n" - " - Auto: If RAW images are detected, the 'Linear' calibration method will be used. Otherwise, the 'Debevec' calibration method will be used.\n" - " - Linear: Disables the calibration and assumes a linear Camera Response Function. If images are encoded in a known colorspace (like sRGB for JPEG), they will be automatically converted to linear.\n" - " - Debevec: Standard method for HDR calibration.\n" - " - Grossberg: Based on a learned database of cameras, allows to reduce the Camera Response Function to a few parameters while keeping all the precision.\n" - " - Laguerre: Simple but robust method estimating the minimal number of parameters.", - values=["auto", "linear", "debevec", "grossberg", "laguerre"], - value="auto", - enabled=lambda node: node.byPass.enabled and not node.byPass.value, - exposed=True, - ), - desc.ChoiceParam( - name="calibrationWeight", - label="Calibration Weight", - description="Weight function used to calibrate camera response:\n" - " - default (automatically selected according to the calibrationMethod)\n" - " - gaussian\n" - " - triangle\n" - " - plateau", - value="default", - values=["default", "gaussian", "triangle", "plateau"], - enabled=lambda node: node.byPass.enabled and not node.byPass.value, - ), - desc.IntParam( - name="channelQuantizationPower", - label="Channel Quantization Power", - description="Quantization level like 8 bits or 10 bits.", - value=10, - range=(8, 14, 1), - advanced=True, - enabled=lambda node: node.byPass.enabled and not node.byPass.value, - exposed=True, - ), - desc.ChoiceParam( - name="workingColorSpace", - label="Working Color Space", - description="Color space in which the data are processed.\n" - "If 'auto' is selected, the working color space will be 'Linear' if RAW images are detected; otherwise, it will be set to 'sRGB'.", - values=COLORSPACES, - value="AUTO", - invalidate=False, - group="user", # not used directly on the command line - enabled=lambda node: node.byPass.enabled and not node.byPass.value, - exposed=True, - ), - desc.IntParam( - name="maxTotalPoints", - label="Max Number Of Points", - description="Maximum number of points used from the sampling.\n" - "This ensures that the number of pixels values extracted by the sampling\n" - "can be managed by the calibration step (in term of computation time and memory usage).", - value=1000000, - range=(8, 10000000, 1000), - advanced=True, - enabled=lambda node: node.byPass.enabled and not node.byPass.value, - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="response", - label="Response File", - description="Path to the output response file.", - value="{nodeCacheFolder}/response_.csv", - ), - ] - - def processChunk(self, chunk): - if chunk.node.nbBrackets.value == 1: - return - # Trick to avoid sending --nbBrackets to the command line when the bracket detection is automatic. - # Otherwise, the AliceVision executable has no way of determining whether the bracket detection was automatic - # or if it was hard-set by the user. - self.commandLine = "aliceVision_LdrToHdrCalibration {allParams}" - if chunk.node.userNbBrackets.value == chunk.node.nbBrackets.value: - self.commandLine += "{bracketsParams}" - super(LdrToHdrCalibration, self).processChunk(chunk) - - @classmethod - def update(cls, node): - from pyalicevision import hdr as avhdr - - 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 - node.userNbBrackets.validValue = True # Reset the status of "userNbBrackets" - - cameraInitOutput = node.input.getLinkParam(recursive=True) - if not cameraInitOutput: - node.nbBrackets.value = 0 - return - if node.userNbBrackets.value != 0: - # The number of brackets has been manually forced: check whether it is valid or not - if cameraInitOutput and cameraInitOutput.node and cameraInitOutput.node.hasAttribute("viewpoints"): - viewpoints = cameraInitOutput.node.viewpoints.value - # The number of brackets should be a multiple of the number of input images - if (len(viewpoints) % node.userNbBrackets.value != 0): - node.userNbBrackets.validValue = False - else: - node.userNbBrackets.validValue = True - node.nbBrackets.value = node.userNbBrackets.value - return - - if not cameraInitOutput.node.hasAttribute("viewpoints"): - if cameraInitOutput.node.hasAttribute("input"): - cameraInitOutput = cameraInitOutput.node.input.getLinkParam(recursive=True) - if cameraInitOutput and cameraInitOutput.node and cameraInitOutput.node.hasAttribute("viewpoints"): - viewpoints = cameraInitOutput.node.viewpoints.value - else: - # No connected CameraInit - node.nbBrackets.value = 0 - return - - inputs = avhdr.vectorli() - for viewpoint in viewpoints: - jsonMetadata = viewpoint.metadata.value - if not jsonMetadata: - # no metadata, we cannot find the number of brackets - node.nbBrackets.value = 0 - return - d = json.loads(jsonMetadata) - - # 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. - node.nbBrackets.value = 1 - return - - exposure = LdrToHdrCalibration.getExposure((float(fnumber), float(shutterSpeed), float(iso))) - - obj = avhdr.LuminanceInfo(viewpoint.viewId.value,viewpoint.path.value, exposure) - inputs.append(obj) - - obj = avhdr.estimateGroups(inputs) - - if len(obj) == 0: - node.nbBrackets.value = 0 - return - - node.nbBrackets.value = len(obj[0]) - - @staticmethod - def getExposure(exp, refIso = 100.0, refFnumber = 1.0): - from pyalicevision import sfmData as avsfmdata - - fnumber, shutterSpeed, iso = exp - obj = avsfmdata.ExposureSetting(shutterSpeed, fnumber, iso) - return obj.getExposure() diff --git a/meshroom/nodes/aliceVision/LdrToHdrMerge.py b/meshroom/nodes/aliceVision/LdrToHdrMerge.py deleted file mode 100644 index ba71e0e21b..0000000000 --- a/meshroom/nodes/aliceVision/LdrToHdrMerge.py +++ /dev/null @@ -1,336 +0,0 @@ -__version__ = "4.1" - -import json - -from meshroom.core import desc -from meshroom.core.utils import COLORSPACES, EXR_STORAGE_DATA_TYPE, VERBOSE_LEVEL - -def findMetadata(d, keys, defaultValue): - v = None - for key in keys: - v = d.get(key, None) - k = key.lower() - if v is not None: - return v - for dk, dv in d.items(): - 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 LdrToHdrMerge(desc.AVCommandLineNode): - commandLine = 'aliceVision_LdrToHdrMerge {allParams}' - size = desc.DynamicNodeSize('input') - parallelization = desc.Parallelization(blockSize=2) - commandLineRange = '--rangeStart {rangeStart} --rangeSize {rangeBlockSize}' - - category = 'Panorama HDR' - documentation = ''' -Merge LDR images into HDR images. -''' - - inputs = [ - desc.File( - name="input", - label="SfMData", - description="Input SfMData file.", - value="", - ), - desc.File( - name="response", - label="Response File", - description="Response file.", - value="", - ), - desc.IntParam( - name="userNbBrackets", - label="Number Of Brackets", - description="Number of exposure brackets per HDR image (0 for automatic detection).", - value=0, - range=(0, 15, 1), - invalidate=False, - group="user", # not used directly on the command line - errorMessage="The set number of brackets is not a multiple of the number of input images.\n" - "Errors will occur during the computation.", - exposed=True, - ), - desc.IntParam( - name="nbBrackets", - label="Automatic Nb Brackets", - description="Number of exposure brackets used per HDR image.\n" - "It is detected automatically from input Viewpoints metadata if 'userNbBrackets'\n" - "is 0, else it is equal to 'userNbBrackets'.", - value=0, - range=(0, 15, 1), - group="bracketsParams", - ), - desc.BoolParam( - name="offsetRefBracketIndexEnabled", - label="Manually Specify Ref Bracket", - description="Manually specify the reference bracket index to control the exposure of the HDR image.", - value=False, - group="user", # not used directly on the command line - ), - desc.IntParam( - name="offsetRefBracketIndex", - label="Offset Ref Bracket Index", - description="0 to use the center bracket.\n" - "+N to use a more exposed bracket or -N to use a less exposed bracket.", - value=1, - range=(-4, 4, 1), - enabled=lambda node: (node.nbBrackets.value != 1 and node.offsetRefBracketIndexEnabled.value), - ), - desc.FloatParam( - name="meanTargetedLumaForMerging", - label="Targeted Luminance For Merging", - description="Expected mean luminance of the HDR images used to compute the final panorama.", - value=0.4, - range=(0.0, 1.0, 0.01), - enabled=lambda node: (node.nbBrackets.value != 1 and not node.offsetRefBracketIndexEnabled.value), - ), - desc.FloatParam( - name="minSignificantValue", - label="Minimum Significant Value", - description="Minimum channel input value to be considered in advanced pixelwise merging.", - value=0.05, - range=(0.0, 1.0, 0.001), - enabled=lambda node: (node.nbBrackets.value != 1), - ), - desc.FloatParam( - name="maxSignificantValue", - label="Maximum Significant Value", - description="Maximum channel input value to be considered in advanced pixelwise merging.", - value=0.995, - range=(0.0, 1.0, 0.001), - enabled=lambda node: (node.nbBrackets.value != 1), - ), - desc.BoolParam( - name="computeLightMasks", - label="Compute Light Masks", - description="Compute masks of low and high lights and missing info.", - value=False, - enabled=lambda node: node.nbBrackets.value != 1, - ), - desc.BoolParam( - name="byPass", - label="Bypass", - description="Bypass HDR creation and use the medium bracket as the source for the next steps.", - value=False, - enabled=lambda node: node.nbBrackets.value != 1, - exposed=True, - ), - desc.BoolParam( - name="keepSourceImageName", - label="Keep Source Image Name", - description="Keep the filename of the input image selected as central image for the output image filename.", - value=False, - ), - desc.ChoiceParam( - name="fusionWeight", - label="Fusion Weight", - description="Weight function used to fuse all LDR images together:\n" - " - gaussian\n" - " - triangle\n" - " - plateau", - value="gaussian", - values=["gaussian", "triangle", "plateau"], - enabled=lambda node: node.byPass.enabled and not node.byPass.value, - ), - desc.IntParam( - name="channelQuantizationPower", - label="Channel Quantization Power", - description="Quantization level like 8 bits or 10 bits.", - value=10, - range=(8, 14, 1), - advanced=True, - enabled=lambda node: node.byPass.enabled and not node.byPass.value, - exposed=True, - ), - desc.ChoiceParam( - name="workingColorSpace", - label="Working Color Space", - description="Color space in which the data are processed.\n" - "If 'auto' is selected, the working color space will be 'Linear' if RAW images are detected; otherwise, it will be set to 'sRGB'.", - values=COLORSPACES, - value="AUTO", - enabled=lambda node: node.byPass.enabled and not node.byPass.value, - exposed=True, - ), - desc.BoolParam( - name="enableHighlight", - label="Enable Highlight", - description="Enable highlights correction.", - value=False, - group="user", # not used directly on the command line - enabled=lambda node: node.byPass.enabled and not node.byPass.value, - ), - desc.FloatParam( - name="highlightCorrectionFactor", - label="Highlights Correction", - description="Pixels saturated in all input images have a partial information about their real luminance.\n" - "We only know that the value should be >= to the standard HDRfusion.\n" - "This parameter allows to perform a post-processing step to put saturated pixels to a constant\n" - "value defined by the `highlightsMaxLuminance` parameter.\n" - "This parameter is float to enable to weight this correction.", - value=1.0, - range=(0.0, 1.0, 0.01), - enabled=lambda node: node.enableHighlight.enabled and node.enableHighlight.value, - ), - desc.FloatParam( - name="highlightTargetLux", - label="Highlight Target Luminance (Lux)", - description="This is an arbitrary target value (in Lux) used to replace the unknown luminance value of the saturated pixels.\n" - "\n" - "Some Outdoor Reference Light Levels:\n" - " - 120,000 lux: Brightest sunlight\n" - " - 110,000 lux: Bright sunlight\n" - " - 20,000 lux: Shade illuminated by entire clear blue sky, midday\n" - " - 1,000 lux: Typical overcast day, midday\n" - " - 400 lux: Sunrise or sunset on a clear day\n" - " - 40 lux: Fully overcast, sunset/sunrise\n" - "\n" - "Some Indoor Reference Light Levels:\n" - " - 20000 lux: Max Usually Used Indoor\n" - " - 750 lux: Supermarkets\n" - " - 500 lux: Office Work\n" - " - 150 lux: Home\n", - value=120000.0, - range=(1000.0, 150000.0, 1.0), - enabled=lambda node: node.enableHighlight.enabled and node.enableHighlight.value and node.highlightCorrectionFactor.value != 0, - ), - desc.ChoiceParam( - name="storageDataType", - label="Storage Data Type", - description="Storage image data type:\n" - " - float: Use full floating point (32 bits per channel).\n" - " - half: Use half float (16 bits per channel).\n" - " - halfFinite: Use half float, but clamp values to avoid non-finite values.\n" - " - auto: Use half float if all values can fit, else use full float.", - values=EXR_STORAGE_DATA_TYPE, - value="float", - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="outputFolder", - label="Folder", - description="Path to the folder containing the merged HDR images.", - value="{nodeCacheFolder}", - group="", # do not export on the command line - ), - desc.File( - name="outSfMData", - label="SfMData", - description="Path to the output SfMData file.", - value="{nodeCacheFolder}/sfmData.sfm", - ), - ] - - @classmethod - def update(cls, node): - from pyalicevision import hdr as avhdr - - 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 - node.userNbBrackets.validValue = True # Reset the status of "userNbBrackets" - - cameraInitOutput = node.input.getLinkParam(recursive=True) - if not cameraInitOutput: - node.nbBrackets.value = 0 - return - if node.userNbBrackets.value != 0: - # The number of brackets has been manually forced: check whether it is valid or not - if cameraInitOutput and cameraInitOutput.node and cameraInitOutput.node.hasAttribute("viewpoints"): - viewpoints = cameraInitOutput.node.viewpoints.value - # The number of brackets should be a multiple of the number of input images - if (len(viewpoints) % node.userNbBrackets.value != 0): - node.userNbBrackets.validValue = False - else: - node.userNbBrackets.validValue = True - node.nbBrackets.value = node.userNbBrackets.value - return - - if not cameraInitOutput.node.hasAttribute("viewpoints"): - if cameraInitOutput.node.hasAttribute("input"): - cameraInitOutput = cameraInitOutput.node.input.getLinkParam(recursive=True) - if cameraInitOutput and cameraInitOutput.node and cameraInitOutput.node.hasAttribute("viewpoints"): - viewpoints = cameraInitOutput.node.viewpoints.value - else: - # No connected CameraInit - node.nbBrackets.value = 0 - return - - inputs = avhdr.vectorli() - for viewpoint in viewpoints: - jsonMetadata = viewpoint.metadata.value - if not jsonMetadata: - # no metadata, we cannot find the number of brackets - node.nbBrackets.value = 0 - return - d = json.loads(jsonMetadata) - - # 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. - node.nbBrackets.value = 1 - return - - exposure = LdrToHdrMerge.getExposure((float(fnumber), float(shutterSpeed), float(iso))) - - obj = avhdr.LuminanceInfo(viewpoint.viewId.value,viewpoint.path.value, exposure) - inputs.append(obj) - - obj = avhdr.estimateGroups(inputs) - - if len(obj) == 0: - node.nbBrackets.value = 0 - return - - node.nbBrackets.value = len(obj[0]) - - @staticmethod - def getExposure(exp, refIso = 100.0, refFnumber = 1.0): - from pyalicevision import sfmData as avsfmdata - - fnumber, shutterSpeed, iso = exp - 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. - # Otherwise, the AliceVision executable has no way of determining whether the bracket detection was automatic - # or if it was hard-set by the user. - self.commandLine = "aliceVision_LdrToHdrMerge {allParams}" - if chunk.node.userNbBrackets.value == chunk.node.nbBrackets.value: - self.commandLine += "{bracketsParams}" - super(LdrToHdrMerge, self).processChunk(chunk) diff --git a/meshroom/nodes/aliceVision/LdrToHdrSampling.py b/meshroom/nodes/aliceVision/LdrToHdrSampling.py deleted file mode 100644 index fa88ccd3c8..0000000000 --- a/meshroom/nodes/aliceVision/LdrToHdrSampling.py +++ /dev/null @@ -1,284 +0,0 @@ -__version__ = "4.0" - -import json - -from meshroom.core import desc -from meshroom.core.utils import COLORSPACES, VERBOSE_LEVEL - - -def findMetadata(d, keys, defaultValue): - v = None - for key in keys: - v = d.get(key, None) - k = key.lower() - if v is not None: - return v - for dk, dv in d.items(): - 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 - # s is the total number of inputs and may include outliers, that will not be used - # during computations and should thus be excluded from the size computation - return (s - node.outliersNb) / divParam.value - - -class LdrToHdrSampling(desc.AVCommandLineNode): - commandLine = 'aliceVision_LdrToHdrSampling {allParams}' - size = DividedInputNodeSize('input', 'nbBrackets') - parallelization = desc.Parallelization(blockSize=2) - commandLineRange = '--rangeStart {rangeStart} --rangeSize {rangeBlockSize}' - - category = 'Panorama HDR' - documentation = ''' -Sample pixels from Low range images for HDR creation. -''' - - outliersNb = 0 # Number of detected outliers among the input images - - inputs = [ - desc.File( - name="input", - label="SfMData", - description="Input SfMData file.", - value="", - ), - desc.IntParam( - name="userNbBrackets", - label="Number Of Brackets", - description="Number of exposure brackets per HDR image (0 for automatic detection).", - value=0, - range=(0, 15, 1), - invalidate=False, - group="user", # not used directly on the command line - errorMessage="The set number of brackets is not a multiple of the number of input images.\n" - "Errors will occur during the computation.", - exposed=True, - ), - desc.IntParam( - name="nbBrackets", - label="Automatic Nb Brackets", - description="Number of exposure brackets used per HDR image.\n" - "It is detected automatically from input Viewpoints metadata if 'userNbBrackets'\n" - "is 0, else it is equal to 'userNbBrackets'.", - value=0, - range=(0, 15, 1), - group="bracketsParams", - ), - desc.BoolParam( - name="byPass", - label="Bypass", - description="Bypass HDR creation and use the medium bracket as the source for the next steps.", - value=False, - enabled=lambda node: node.nbBrackets.value != 1, - exposed=True, - ), - desc.ChoiceParam( - name="calibrationMethod", - label="Calibration Method", - description="Method used for camera calibration:\n" - " - Auto: If RAW images are detected, the 'Linear' calibration method will be used. Otherwise, the 'Debevec' calibration method will be used.\n" - " - Linear: Disables the calibration and assumes a linear Camera Response Function. If images are encoded in a known colorspace (like sRGB for JPEG), they will be automatically converted to linear.\n" - " - Debevec: Standard method for HDR calibration.\n" - " - Grossberg: Based on a learned database of cameras, allows to reduce the Camera Response Function to a few parameters while keeping all the precision.\n" - " - Laguerre: Simple but robust method estimating the minimal number of parameters.", - values=["auto", "linear", "debevec", "grossberg", "laguerre"], - value="auto", - enabled=lambda node: node.byPass.enabled and not node.byPass.value, - exposed=True, - ), - desc.IntParam( - name="channelQuantizationPower", - label="Channel Quantization Power", - description="Quantization level like 8 bits or 10 bits.", - value=10, - range=(8, 14, 1), - advanced=True, - enabled=lambda node: node.byPass.enabled and not node.byPass.value, - exposed=True, - ), - desc.ChoiceParam( - name="workingColorSpace", - label="Working Color Space", - description="Color space in which the data are processed.\n" - "If 'auto' is selected, the working color space will be 'Linear' if RAW images are detected; otherwise, it will be set to 'sRGB'.", - values=COLORSPACES, - value="AUTO", - enabled=lambda node: node.byPass.enabled and not node.byPass.value, - exposed=True, - ), - desc.IntParam( - name="blockSize", - label="Block Size", - description="Size of the image tile to extract a sample.", - value=256, - range=(8, 1024, 1), - advanced=True, - enabled=lambda node: node.byPass.enabled and not node.byPass.value, - ), - desc.IntParam( - name="radius", - label="Patch Radius", - description="Radius of the patch used to analyze the sample statistics.", - value=5, - range=(0, 10, 1), - advanced=True, - enabled=lambda node: node.byPass.enabled and not node.byPass.value, - ), - desc.IntParam( - name="maxCountSample", - label="Max Number Of Samples", - description="Maximum number of samples per image group.", - value=200, - range=(10, 1000, 10), - advanced=True, - enabled=lambda node: node.byPass.enabled and not node.byPass.value, - ), - desc.BoolParam( - name="debug", - label="Export Debug Files", - description="Export debug files to analyze the sampling strategy.", - value=False, - invalidate=False, - enabled=lambda node: node.byPass.enabled and not node.byPass.value, - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="output", - label="Folder", - description="Output path for the samples.", - value="{nodeCacheFolder}", - ), - ] - - def processChunk(self, chunk): - if chunk.node.nbBrackets.value == 1: - return - # Trick to avoid sending --nbBrackets to the command line when the bracket detection is automatic. - # Otherwise, the AliceVision executable has no way of determining whether the bracket detection was automatic - # or if it was hard-set by the user. - self.commandLine = "aliceVision_LdrToHdrSampling {allParams}" - if chunk.node.userNbBrackets.value == chunk.node.nbBrackets.value: - self.commandLine += "{bracketsParams}" - super(LdrToHdrSampling, self).processChunk(chunk) - - @classmethod - def update(cls, node): - from pyalicevision import hdr as avhdr - - 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 - node.outliersNb = 0 # Reset the number of detected outliers - node.userNbBrackets.validValue = True # Reset the status of "userNbBrackets" - - cameraInitOutput = node.input.getLinkParam(recursive=True) - if not cameraInitOutput: - node.nbBrackets.value = 0 - return - if node.userNbBrackets.value != 0: - # The number of brackets has been manually forced: check whether it is valid or not - if cameraInitOutput and cameraInitOutput.node and cameraInitOutput.node.hasAttribute("viewpoints"): - viewpoints = cameraInitOutput.node.viewpoints.value - # The number of brackets should be a multiple of the number of input images - if (len(viewpoints) % node.userNbBrackets.value != 0): - node.userNbBrackets.validValue = False - else: - node.userNbBrackets.validValue = True - node.nbBrackets.value = node.userNbBrackets.value - return - - if not cameraInitOutput.node.hasAttribute("viewpoints"): - if cameraInitOutput.node.hasAttribute("input"): - cameraInitOutput = cameraInitOutput.node.input.getLinkParam(recursive=True) - if cameraInitOutput and cameraInitOutput.node and cameraInitOutput.node.hasAttribute("viewpoints"): - viewpoints = cameraInitOutput.node.viewpoints.value - else: - # No connected CameraInit - node.nbBrackets.value = 0 - return - - inputs = avhdr.vectorli() - for viewpoint in viewpoints: - jsonMetadata = viewpoint.metadata.value - if not jsonMetadata: - # no metadata, we cannot find the number of brackets - node.nbBrackets.value = 0 - return - d = json.loads(jsonMetadata) - - # 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. - node.nbBrackets.value = 1 - return - - exposure = LdrToHdrSampling.getExposure((float(fnumber), float(shutterSpeed), float(iso))) - - obj = avhdr.LuminanceInfo(viewpoint.viewId.value,viewpoint.path.value, exposure) - inputs.append(obj) - - obj = avhdr.estimateGroups(inputs) - - if len(obj) == 0: - node.nbBrackets.value = 0 - return - - bracketSize = len(obj[0]) - bracketCount = len(obj) - - node.nbBrackets.value = bracketSize - node.outliersNb = len(inputs) - (bracketSize * bracketCount) - - @staticmethod - def getExposure(exp, refIso = 100.0, refFnumber = 1.0): - from pyalicevision import sfmData as avsfmdata - - fnumber, shutterSpeed, iso = exp - obj = avsfmdata.ExposureSetting(shutterSpeed, fnumber, iso) - return obj.getExposure() diff --git a/meshroom/nodes/aliceVision/LidarDecimating.py b/meshroom/nodes/aliceVision/LidarDecimating.py deleted file mode 100644 index 8eaf484fc5..0000000000 --- a/meshroom/nodes/aliceVision/LidarDecimating.py +++ /dev/null @@ -1,57 +0,0 @@ -__version__ = "1.0" - -from meshroom.core import desc -from meshroom.core.utils import VERBOSE_LEVEL - -class LidarDecimating(desc.AVCommandLineNode): - commandLine = 'aliceVision_lidarDecimating {allParams}' - - size = desc.StaticNodeSize(10) - parallelization = desc.Parallelization(blockSize=1) - commandLineRange = '--rangeStart {rangeStart} --rangeSize {rangeFullSize}' - - cpu = desc.Level.INTENSIVE - ram = desc.Level.INTENSIVE - - category = 'Dense Reconstruction' - documentation = ''' - This node simplifies previously reconstructed meshes from Lidar. - ''' - - inputs = [ - desc.File( - name="input", - label="Input JSON", - description="Input JSON file with description of inputs.", - value="", - ), - desc.FloatParam( - name="errorLimit", - label="Error Limit", - description="Maximal distance (in meters) allowed.", - value=0.001, - range=(0.0, 1.0, 0.001), - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="output", - label="Sub-Meshes Directory", - description="Output directory for sub-meshes.", - value="{nodeCacheFolder}", - ), - desc.File( - name="outputJson", - label="Scene Description", - description="Output scene description.", - value="{nodeCacheFolder}/scene.json", - ), - ] diff --git a/meshroom/nodes/aliceVision/LidarMerging.py b/meshroom/nodes/aliceVision/LidarMerging.py deleted file mode 100644 index e107d7c4a0..0000000000 --- a/meshroom/nodes/aliceVision/LidarMerging.py +++ /dev/null @@ -1,40 +0,0 @@ -__version__ = "1.0" - -from meshroom.core import desc -from meshroom.core.utils import VERBOSE_LEVEL - -class LidarMerging(desc.AVCommandLineNode): - commandLine = 'aliceVision_lidarMerging {allParams}' - - cpu = desc.Level.INTENSIVE - ram = desc.Level.INTENSIVE - - category = 'Dense Reconstruction' - documentation = ''' - This node merge several meshes into one. - ''' - - inputs = [ - desc.File( - name="input", - label="Input JSON", - description="Input JSON file with description of inputs.", - value="", - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="output", - label="Mesh Path Output", - description="Output directory for mesh.", - value="{nodeCacheFolder}/output.obj", - ), - ] diff --git a/meshroom/nodes/aliceVision/LidarMeshing.py b/meshroom/nodes/aliceVision/LidarMeshing.py deleted file mode 100644 index 3ce1a7071f..0000000000 --- a/meshroom/nodes/aliceVision/LidarMeshing.py +++ /dev/null @@ -1,137 +0,0 @@ -__version__ = "1.0" - -from meshroom.core import desc -from meshroom.core.utils import VERBOSE_LEVEL - -class LidarMeshing(desc.AVCommandLineNode): - commandLine = 'aliceVision_lidarMeshing {allParams}' - - size = desc.StaticNodeSize(10) - parallelization = desc.Parallelization(blockSize=1) - commandLineRange = '--rangeStart {rangeStart} --rangeSize {rangeFullSize}' - - cpu = desc.Level.INTENSIVE - ram = desc.Level.INTENSIVE - - category = 'Dense Reconstruction' - documentation = ''' - This node creates a dense geometric surface representation of the Lidar measurements. - ''' - - inputs = [ - desc.File( - name="input", - label="Input JSON", - description="Input JSON file with description of inputs.", - value="", - ), - desc.BoolParam( - name="useBoundingBox", - label="Custom Bounding Box", - description="Edit the meshing bounding box.\n" - "If enabled, it takes priority over the 'Estimate Space From SfM' option.\n" - "Parameters can be adjusted in advanced settings.", - value=False, - group="", - ), - desc.GroupAttribute( - name="boundingBox", - label="Bounding Box Settings", - description="Translation, rotation and scale of the bounding box.", - groupDesc=[ - desc.GroupAttribute( - name="bboxTranslation", - label="Translation", - description="Position in space.", - groupDesc=[ - desc.FloatParam( - name="x", label="x", description="X offset.", - value=0.0, - range=(-20.0, 20.0, 0.01), - ), - desc.FloatParam( - name="y", label="y", description="Y offset.", - value=0.0, - range=(-20.0, 20.0, 0.01), - ), - desc.FloatParam( - name="z", label="z", description="Z offset.", - value=0.0, - range=(-20.0, 20.0, 0.01), - ), - ], - joinChar=",", - ), - desc.GroupAttribute( - name="bboxRotation", - label="Euler Rotation", - description="Rotation in Euler degrees.", - groupDesc=[ - desc.FloatParam( - name="x", label="x", description="Euler X rotation.", - value=0.0, - range=(-90.0, 90.0, 1.0), - ), - desc.FloatParam( - name="y", label="y", description="Euler Y rotation.", - value=0.0, - range=(-180.0, 180.0, 1.0), - ), - desc.FloatParam( - name="z", label="z", description="Euler Z rotation.", - value=0.0, - range=(-180.0, 180.0, 1.0), - ), - ], - joinChar=",", - ), - desc.GroupAttribute( - name="bboxScale", - label="Scale", - description="Scale of the bounding box.", - groupDesc=[ - desc.FloatParam( - name="x", label="x", description="X scale.", - value=1.0, - range=(0.0, 20.0, 0.01), - ), - desc.FloatParam( - name="y", label="y", description="Y scale.", - value=1.0, - range=(0.0, 20.0, 0.01), - ), - desc.FloatParam( - name="z", label="z", description="Z scale.", - value=1.0, - range=(0.0, 20.0, 0.01), - ), - ], - joinChar=",", - ), - ], - joinChar=",", - enabled=lambda node: node.useBoundingBox.value, - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="output", - label="Sub-Meshes Directory", - description="Output directory for sub-meshes", - value="{nodeCacheFolder}", - ), - desc.File( - name="outputJson", - label="Scene Description", - description="Output scene description.", - value="{nodeCacheFolder}/scene.json", - ), - ] diff --git a/meshroom/nodes/aliceVision/LightingCalibration.py b/meshroom/nodes/aliceVision/LightingCalibration.py deleted file mode 100644 index 01b1f793b6..0000000000 --- a/meshroom/nodes/aliceVision/LightingCalibration.py +++ /dev/null @@ -1,73 +0,0 @@ -__version__ = "1.0" - -from meshroom.core import desc -from meshroom.core.utils import VERBOSE_LEVEL - - -class LightingCalibration(desc.CommandLineNode): - commandLine = 'aliceVision_lightingCalibration {allParams}' - category = 'Photometric Stereo' - documentation = ''' -Evaluate the lighting in a scene using spheres placed in the scene. -Can also be used to calibrate a lighting dome (RTI type). -''' - - inputs = [ - desc.File( - name="inputPath", - label="Input SfMData", - description="Input SfMData file.", - value="", - ), - desc.File( - name="inputDetection", - label="Sphere Detection File", - description="Input JSON file containing sphere centers and radiuses.", - value="", - ), - desc.BoolParam( - name="saveAsModel", - label="Save As Model", - description="Check if this calibration file will be used with other datasets.", - value=False, - ), - desc.BoolParam( - name="ellipticEstimation", - label="Use elliptic estimation", - description="Consider the right projection of the sphere. Fit the circle tool on the small axe of the ellipse.", - value=False, - ), - desc.ChoiceParam( - name="method", - label="Calibration Method", - description="Method used for light calibration.\n" - "Use 'brightestPoint' for shiny spheres and 'whiteSphere' for white matte spheres.\n" - "Spherical Harmonic lighting can be estimated using 'SH' method.", - values=["brightestPoint", "whiteSphere", "SH"], - value="brightestPoint", - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="outputFile", - label="Light File", - description="Light information will be written here.", - value="{nodeCacheFolder}/lights.json", - ), - desc.File( - name="lightingEstimationVisualization", - label="Estimated Lighting Visualization", - description="Estimated Lighting Visualization.", - semantic="image", - value="{nodeCacheFolder}/_{methodValue}.png", - group=None, - ), - ] diff --git a/meshroom/nodes/aliceVision/LightingEstimation.py b/meshroom/nodes/aliceVision/LightingEstimation.py deleted file mode 100644 index 3e3193c1fd..0000000000 --- a/meshroom/nodes/aliceVision/LightingEstimation.py +++ /dev/null @@ -1,82 +0,0 @@ -__version__ = "1.0" - -from meshroom.core import desc -from meshroom.core.utils import VERBOSE_LEVEL - - -class LightingEstimation(desc.AVCommandLineNode): - commandLine = 'aliceVision_lightingEstimation {allParams}' - - category = 'Utils' - documentation = ''' - ''' - - inputs = [ - desc.File( - name="input", - label="Input SfMData", - description="Input SfMData file.", - value="", - ), - desc.File( - name="depthMapsFilterFolder", - label="Filtered Depth Maps Folder", - description="Input filtered depth maps folder.", - value="", - ), - desc.File( - name="imagesFolder", - label="Images Folder", - description="Use images from a specific folder instead of those specify in the SfMData file.\n" - "Filename should be the image UID.", - value="", - ), - desc.ChoiceParam( - name="lightingEstimationMode", - label="Lighting Estimation Mode", - description="Lighting estimation mode.", - value="global", - values=["global", "per_image"], - advanced=True, - ), - desc.ChoiceParam( - name="lightingColor", - label="Lighting Color Mode", - description="Lighting color mode.", - value="RGB", - values=["RGB", "Luminance"], - advanced=True, - ), - desc.ChoiceParam( - name="albedoEstimationName", - label="Albedo Estimation Name", - description="Albedo estimation method used for light estimation.", - value="constant", - values=["constant", "picture", "median_filter", "blur_filter"], - advanced=True, - ), - desc.IntParam( - name="albedoEstimationFilterSize", - label="Albedo Estimation Filter Size", - description="Albedo filter size for estimation method using filter.", - value=3, - range=(0, 100, 1), - advanced=True, - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="output", - label="Folder", - description="Folder for output lighting vector files.", - value="{nodeCacheFolder}", - ), - ] diff --git a/meshroom/nodes/aliceVision/MaskProcessing.py b/meshroom/nodes/aliceVision/MaskProcessing.py deleted file mode 100644 index 6d6e56457a..0000000000 --- a/meshroom/nodes/aliceVision/MaskProcessing.py +++ /dev/null @@ -1,85 +0,0 @@ -__version__ = "1.0" - -from meshroom.core import desc -from meshroom.core.utils import DESCRIBER_TYPES, VERBOSE_LEVEL - -import os.path - -class MaskProcessingNodeSize(desc.DynamicNodeSize): - """ - MaskProcessingNodeSize expresses a dependency to multiple input attributess to define - the size of a Node in terms of individual tasks for parallelization. - """ - def __init__(self, param): - self._params = param - - def computeSize(self, node): - - size = 0 - - for input in node.attribute(self._params).value: - paramName = input.getFullName() - param = node.attribute(paramName) - if param.isLink: - size = max(size, param.getLinkParam().node.size) - - return size - - -class MaskProcessing(desc.AVCommandLineNode): - commandLine = 'aliceVision_maskProcessing {allParams}' - size = MaskProcessingNodeSize("inputs") - - category = 'Utils' - documentation = ''' - Perform operations on a list of masks with the same names - ''' - - inputs = [ - desc.ListAttribute( - elementDesc=desc.File( - name="input", - label="Input Directory", - description="A directory with a set of mask.", - value="", - ), - name="inputs", - label="Input Directories", - description="A set of directories containing masks with the same names.", - exposed=True, - ), - desc.ChoiceParam( - name="operator", - label="Operator", - description="Operator: Binary operator\n" - "OR: applies binary OR between all the masks\n" - "AND: applies binary AND between all the masks\n" - "NOT: applies binary NOT to the first mask in the list\n", - value="and", - values=["or", "and", "not"], - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ) - ] - - outputs = [ - desc.File( - name="output", - label="Output", - description="Path to the output directory.", - value="{nodeCacheFolder}", - ), - desc.File( - name="masks", - label="Masks", - description="Processed segmentation masks.", - semantic="imageList", - value= "{nodeCacheFolder}/*.exr", - group="", - ), - ] diff --git a/meshroom/nodes/aliceVision/MergeMeshes.py b/meshroom/nodes/aliceVision/MergeMeshes.py deleted file mode 100644 index 311e7f1b48..0000000000 --- a/meshroom/nodes/aliceVision/MergeMeshes.py +++ /dev/null @@ -1,69 +0,0 @@ -__version__ = "1.0" - -from meshroom.core import desc -from meshroom.core.utils import VERBOSE_LEVEL - - -class MergeMeshes(desc.AVCommandLineNode): - commandLine = 'aliceVision_mergeMeshes {allParams}' - - category = 'Utils' - documentation = ''' -This node allows to merge two meshes in one. - -Operation types used to merge two meshes: - -- boolean_union: Create a new mesh with the combined volume of the two input meshes. -- boolean_intersection: Create a new mesh from the intersected volumes of the two input meshes. -- boolean_difference: Create a new mesh from the volume of the first input mesh subtracted by the second input mesh. -''' - - inputs = [ - desc.File( - name="inputFirstMesh", - label="First Mesh", - description="Input first mesh (*.obj, *.mesh, *.meshb, *.ply, *.off, *.stl).", - value="", - ), - desc.File( - name="inputSecondMesh", - label="Second Mesh", - description="Input second mesh (*.obj, *.mesh, *.meshb, *.ply, *.off, *.stl).", - value="", - ), - desc.ChoiceParam( - name="mergeOperation", - label="Merge Operation", - description="Operation types used to merge two meshes.", - value="boolean_union", - values=["boolean_union", "boolean_intersection", "boolean_difference"], - ), - desc.BoolParam( - name="preProcess", - label="Pre-Process", - description="Pre-process the input meshes in order to avoid geometric errors in the merging process.", - value=True, - ), - desc.BoolParam( - name="postProcess", - label="Post-Process", - description="Post-process the output mesh in order to avoid future geometric errors.", - value=True, - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="output", - label="Mesh", - description="Output mesh (*.obj, *.mesh, *.meshb, *.ply, *.off, *.stl).", - value="{nodeCacheFolder}/mesh.stl", - ), - ] diff --git a/meshroom/nodes/aliceVision/MeshDecimate.py b/meshroom/nodes/aliceVision/MeshDecimate.py deleted file mode 100644 index a6b092609b..0000000000 --- a/meshroom/nodes/aliceVision/MeshDecimate.py +++ /dev/null @@ -1,77 +0,0 @@ -__version__ = "1.0" - -from meshroom.core import desc -from meshroom.core.utils import VERBOSE_LEVEL - - -class MeshDecimate(desc.AVCommandLineNode): - commandLine = 'aliceVision_meshDecimate {allParams}' - cpu = desc.Level.NORMAL - ram = desc.Level.NORMAL - - category = 'Mesh Post-Processing' - documentation = ''' -This node allows to reduce the density of the Mesh. -''' - - inputs = [ - desc.File( - name="input", - label="Mesh", - description="Input mesh in the OBJ format.", - value="", - ), - desc.FloatParam( - name="simplificationFactor", - label="Simplification Factor", - description="Simplification factor for the decimation.", - value=0.5, - range=(0.0, 1.0, 0.01), - ), - desc.IntParam( - name="nbVertices", - label="Fixed Number of Vertices", - description="Fixed number of output vertices.", - value=0, - range=(0, 1000000, 1), - ), - desc.IntParam( - name="minVertices", - label="Min Vertices", - description="Minimum number of output vertices.", - value=0, - range=(0, 1000000, 1), - ), - desc.IntParam( - name="maxVertices", - label="Max Vertices", - description="Maximum number of output vertices.", - value=0, - range=(0, 1000000, 1), - ), - desc.BoolParam( - name="flipNormals", - label="Flip Normals", - description="Option to flip face normals.\n" - "It can be needed as it depends on the vertices order in triangles\n" - "and the convention changes from one software to another.", - value=False, - advanced=True, - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="output", - label="Mesh", - description="Output mesh in the OBJ file format.", - value="{nodeCacheFolder}/mesh.obj", - ), - ] diff --git a/meshroom/nodes/aliceVision/MeshDenoising.py b/meshroom/nodes/aliceVision/MeshDenoising.py deleted file mode 100644 index a7329e45b6..0000000000 --- a/meshroom/nodes/aliceVision/MeshDenoising.py +++ /dev/null @@ -1,92 +0,0 @@ -__version__ = "1.0" - -from meshroom.core import desc -from meshroom.core.utils import VERBOSE_LEVEL - - -class MeshDenoising(desc.AVCommandLineNode): - commandLine = 'aliceVision_meshDenoising {allParams}' - - category = 'Mesh Post-Processing' - documentation = ''' -This experimental node allows to reduce noise from a Mesh. -for now, the parameters are difficult to control and vary a lot from one dataset to another. -''' - - inputs = [ - desc.File( - name="input", - label="Mesh", - description="Input mesh in the OBJ file format.", - value="", - ), - desc.IntParam( - name="denoisingIterations", - label="Denoising Iterations", - description="Number of denoising iterations.", - value=5, - range=(0, 30, 1), - ), - desc.FloatParam( - name="meshUpdateClosenessWeight", - label="Mesh Update Closeness Weight", - description="Closeness weight for mesh update. Must be positive.", - value=0.001, - range=(0.0, 0.1, 0.001), - ), - desc.FloatParam( - name="lambda", - label="Lambda", - description="Regularization weight.", - value=2.0, - range=(0.0, 10.0, 0.01), - ), - desc.FloatParam( - name="eta", - label="Eta", - description="Gaussian standard deviation for spatial weight, \n" - "scaled by the average distance between adjacent face centroids.\n" - "Must be positive.", - value=1.5, - range=(0.0, 20.0, 0.01), - ), - desc.FloatParam( - name="mu", - label="Mu", - description="Gaussian standard deviation for guidance weight.", - value=1.5, - range=(0.0, 10.0, 0.01), - ), - desc.FloatParam( - name="nu", - label="Nu", - description="Gaussian standard deviation for signal weight.", - value=0.3, - range=(0.0, 5.0, 0.01), - ), - desc.ChoiceParam( - name="meshUpdateMethod", - label="Mesh Update Method", - description="Mesh ppdate method:\n" - " - ITERATIVE_UPDATE (default): ShapeUp styled iterative solver.\n" - " - POISSON_UPDATE: Poisson-based update from [Wang et al. 2015] 'Rolling guidance normal filter for geometric processing'.", - value=0, - values=[0, 1], - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="output", - label="Output", - description="Output mesh in the OBJ file format.", - value="{nodeCacheFolder}/mesh.obj", - ), - ] diff --git a/meshroom/nodes/aliceVision/MeshFiltering.py b/meshroom/nodes/aliceVision/MeshFiltering.py deleted file mode 100644 index 6eb91d1052..0000000000 --- a/meshroom/nodes/aliceVision/MeshFiltering.py +++ /dev/null @@ -1,117 +0,0 @@ -__version__ = "3.0" - -from meshroom.core import desc -from meshroom.core.utils import VERBOSE_LEVEL - - -class MeshFiltering(desc.AVCommandLineNode): - commandLine = 'aliceVision_meshFiltering {allParams}' - - category = 'Dense Reconstruction' - documentation = ''' -This node applies a Laplacian filtering to remove local defects from the raw Meshing cut. -''' - - inputs = [ - desc.File( - name="inputMesh", - label="Mesh", - description="Input mesh file.", - value="", - ), - desc.ChoiceParam( - name="outputMeshFileType", - label="Mesh Type", - description="File type for the output mesh.", - value="obj", - values=["gltf", "obj", "fbx", "stl"], - group="", - ), - desc.BoolParam( - name="keepLargestMeshOnly", - label="Keep Only The Largest Mesh", - description="Keep only the largest connected triangles group.", - value=False, - ), - desc.ChoiceParam( - name="smoothingSubset", - label="Smoothing Subset", - description="Subset for smoothing (all, surface_boundaries, surface_inner_part).", - value="all", - values=["all", "surface_boundaries", "surface_inner_part"], - advanced=True, - ), - desc.IntParam( - name="smoothingBoundariesNeighbours", - label="Smoothing Boundaries Neighbours", - description="Neighbours of the boundaries to consider.", - value=0, - range=(0, 20, 1), - advanced=True, - ), - desc.IntParam( - name="smoothingIterations", - label="Smoothing Iterations", - description="Number of smoothing iterations.", - value=5, - range=(0, 50, 1), - ), - desc.FloatParam( - name="smoothingLambda", - label="Smoothing Lambda", - description="Smoothing size.", - value=1.0, - range=(0.0, 10.0, 0.1), - advanced=True, - ), - desc.ChoiceParam( - name="filteringSubset", - label="Filtering Subset", - description="Subset for filtering (all, surface_boundaries, surface_inner_part).", - value="all", - values=["all", "surface_boundaries", "surface_inner_part"], - advanced=True, - ), - desc.IntParam( - name="filteringIterations", - label="Filtering Iterations", - description="Number of filtering iterations.", - value=1, - range=(0, 20, 1), - advanced=True, - ), - desc.FloatParam( - name="filterLargeTrianglesFactor", - label="Filter Large Triangles Factor", - description="Remove all large triangles.\n" - "We consider a triangle as large if one edge is bigger than N times the average edge length.\n" - "0 disables the filtering.", - value=60.0, - range=(0.0, 100.0, 0.1), - ), - desc.FloatParam( - name="filterTrianglesRatio", - label="Filter Triangles Ratio", - description="Remove all triangles by ratio (largest edge /smallest edge).\n" - "0 disables the filtering.", - value=0.0, - range=(1.0, 50.0, 0.1), - advanced=True, - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="outputMesh", - label="Mesh", - description="Output mesh file.", - value="{nodeCacheFolder}/mesh.{outputMeshFileTypeValue}", - ), - ] diff --git a/meshroom/nodes/aliceVision/MeshMasking.py b/meshroom/nodes/aliceVision/MeshMasking.py deleted file mode 100644 index 45fa5f329b..0000000000 --- a/meshroom/nodes/aliceVision/MeshMasking.py +++ /dev/null @@ -1,103 +0,0 @@ -__version__ = "1.1" - -from meshroom.core import desc -from meshroom.core.utils import VERBOSE_LEVEL - - -class MeshMasking(desc.AVCommandLineNode): - commandLine = 'aliceVision_meshMasking {allParams}' - category = 'Mesh Post-Processing' - documentation = ''' -Decimate triangles based on image masks. -''' - - inputs = [ - desc.File( - name="input", - label="Dense SfMData", - description="Dense SfMData file.", - value="", - ), - desc.File( - name="inputMesh", - label="Input Mesh", - description="Input mesh.", - value="", - ), - desc.ChoiceParam( - name="outputMeshFileType", - label="Output Mesh Type", - description="File type of the output mesh.", - value="obj", - values=["obj", "gltf", "fbx", "stl"], - group="", - ), - desc.ListAttribute( - elementDesc=desc.File( - name="masksFolder", - label="Masks Folder", - description="Folder containing some masks.", - value="", - ), - name="masksFolders", - label="Masks Folders", - description="Use masks from specific folder(s). Filename should be the same or the image UID.", - ), - desc.ChoiceParam( - name="maskExtension", - label="Mask Extension", - description="File extension for the masks to use.", - value="png", - values=["exr", "jpg", "png"], - ), - desc.IntParam( - name="threshold", - label="Threshold", - description="The minimum number of visibilities to keep a vertex.", - value=1, - range=(1, 100, 1), - ), - desc.BoolParam( - name="smoothBoundary", - label="Smooth Boundary", - description="Modify the triangles at the boundary to fit the masks.", - value=False, - ), - desc.BoolParam( - name="invert", - label="Invert", - description="If ticked, the selected area is ignored.\n" - "If not, only the selected area is considered.", - value=False, - ), - desc.BoolParam( - name="undistortMasks", - label="Undistort Masks", - description="Undistort the masks with the same parameters as the matching image.\n" - "Select it if the masks are drawn on the original images.", - value=False, - ), - desc.BoolParam( - name="usePointsVisibilities", - label="Use Points visibilities", - description="Use the points visibilities from the meshing to filter triangles.\n" - "Example: when they are occluded, back-face, etc.", - value=False, - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="outputMesh", - label="Mesh", - description="Output mesh file.", - value="{nodeCacheFolder}/mesh.{outputMeshFileTypeValue}", - ), - ] diff --git a/meshroom/nodes/aliceVision/MeshRemoveUnseenFaces.py b/meshroom/nodes/aliceVision/MeshRemoveUnseenFaces.py deleted file mode 100644 index c82e3094bf..0000000000 --- a/meshroom/nodes/aliceVision/MeshRemoveUnseenFaces.py +++ /dev/null @@ -1,69 +0,0 @@ -__version__ = "3.0" - -from meshroom.core import desc -from meshroom.core.utils import VERBOSE_LEVEL - - -class MeshRemoveUnseenFaces(desc.AVCommandLineNode): - commandLine = 'aliceVision_meshRemoveUnseenFaces {allParams}' - - cpu = desc.Level.INTENSIVE - ram = desc.Level.NORMAL - - category = 'Dense Reconstruction' - documentation = ''' -Remove triangles from the mesh when the vertices are not visible by any camera. -''' - - inputs = [ - desc.File( - name="input", - label="SfMData", - description="Input SfMData file.", - value="", - ), - desc.File( - name="inputMesh", - label="Mesh", - description="Input Mesh file.", - value="", - ), - desc.ChoiceParam( - name="outputMeshFileType", - label="Mesh Type", - description="File type for the output mesh.", - value="obj", - values=["gltf", "obj", "fbx", "stl"], - group="", - ), - desc.IntParam( - name="minObservations", - label="Min Observations", - description="Minimal number of observations to keep a vertex.", - value=1, - range=(0, 5, 1), - ), - desc.IntParam( - name="minVertices", - label="Min Vertices to Remove a Triangle", - description="Minimal number of killed vertices in a triangle to remove the triangle.", - value=3, - range=(1, 3, 1), - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="outputMesh", - label="Mesh", - description="Output mesh file.", - value="{nodeCacheFolder}/mesh.{outputMeshFileTypeValue}", - ), - ] diff --git a/meshroom/nodes/aliceVision/MeshResampling.py b/meshroom/nodes/aliceVision/MeshResampling.py deleted file mode 100644 index d96373adfe..0000000000 --- a/meshroom/nodes/aliceVision/MeshResampling.py +++ /dev/null @@ -1,82 +0,0 @@ -__version__ = "1.0" - -from meshroom.core import desc -from meshroom.core.utils import VERBOSE_LEVEL - - -class MeshResampling(desc.AVCommandLineNode): - commandLine = 'aliceVision_meshResampling {allParams}' - cpu = desc.Level.NORMAL - ram = desc.Level.NORMAL - - category = 'Mesh Post-Processing' - documentation = ''' -This node allows to recompute the mesh surface with a new topology and uniform density. -''' - - inputs = [ - desc.File( - name="input", - label="Input Mesh", - description="Input mesh in the OBJ file format.", - value="", - ), - desc.FloatParam( - name="simplificationFactor", - label="Simplification Factor", - description="Simplification factor for the resampling.", - value=0.5, - range=(0.0, 1.0, 0.01), - ), - desc.IntParam( - name="nbVertices", - label="Fixed Number Of Vertices", - description="Fixed number of output vertices.", - value=0, - range=(0, 1000000, 1), - ), - desc.IntParam( - name="minVertices", - label="Min Vertices", - description="Minimum number of output vertices.", - value=0, - range=(0, 1000000, 1), - ), - desc.IntParam( - name="maxVertices", - label="Max Vertices", - description="Maximum number of output vertices.", - value=0, - range=(0, 1000000, 1), - ), - desc.IntParam( - name="nbLloydIter", - label="Number Of Pre-Smoothing Iteration", - description="Number of iterations for Lloyd pre-smoothing.", - value=40, - range=(0, 100, 1), - ), - desc.BoolParam( - name="flipNormals", - label="Flip Normals", - description="Option to flip face normals.\n" - "It can be needed as it depends on the vertices order in triangles and the convention changes from one software to another.", - value=False, - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="output", - label="Mesh", - description="Output mesh in the OBJ file format.", - value="{nodeCacheFolder}/mesh.obj", - ), - ] diff --git a/meshroom/nodes/aliceVision/Meshing.py b/meshroom/nodes/aliceVision/Meshing.py deleted file mode 100644 index b01fe33e85..0000000000 --- a/meshroom/nodes/aliceVision/Meshing.py +++ /dev/null @@ -1,483 +0,0 @@ -__version__ = "7.0" - -from meshroom.core import desc -from meshroom.core.utils import VERBOSE_LEVEL - - -class Meshing(desc.AVCommandLineNode): - commandLine = 'aliceVision_meshing {allParams}' - - cpu = desc.Level.INTENSIVE - ram = desc.Level.INTENSIVE - - category = 'Dense Reconstruction' - documentation = ''' -This node creates a dense geometric surface representation of the scene. - -First, it fuses all the depth maps into a global dense point cloud with an adaptive resolution. -It then performs a 3D Delaunay tetrahedralization and a voting procedure is done to compute weights on cells and weights on facets connecting the cells. -A Graph Cut Max-Flow is applied to optimally cut the volume. This cut represents the extracted mesh surface. - -## Online -[https://alicevision.org/#photogrammetry/meshing](https://alicevision.org/#photogrammetry/meshing) -''' - - inputs = [ - desc.File( - name="input", - label="SfmData", - description="Input SfMData file.", - value="", - ), - desc.File( - name="depthMapsFolder", - label="Depth Maps Folder", - description="Input depth maps folder.", - value="", - ), - desc.ChoiceParam( - name="outputMeshFileType", - label="Mesh Type", - description="File type for the output mesh.", - value="obj", - values=["gltf", "obj", "fbx", "stl"], - group="", - ), - desc.BoolParam( - name="useBoundingBox", - label="Custom Bounding Box", - description="Edit the meshing bounding box.\n" - "If enabled, it takes priority over the 'Estimate Space From SfM' option.\n" - "Parameters can be adjusted in advanced settings.", - value=False, - group="", - ), - desc.GroupAttribute( - name="boundingBox", - label="Bounding Box Settings", - description="Translation, rotation and scale of the bounding box.", - groupDesc=[ - desc.GroupAttribute( - name="bboxTranslation", - label="Translation", - description="Position in space.", - groupDesc=[ - desc.FloatParam( - name="x", label="x", description="X offset.", - value=0.0, - range=(-20.0, 20.0, 0.01), - ), - desc.FloatParam( - name="y", label="y", description="Y offset.", - value=0.0, - range=(-20.0, 20.0, 0.01), - ), - desc.FloatParam( - name="z", label="z", description="Z offset.", - value=0.0, - range=(-20.0, 20.0, 0.01), - ), - ], - joinChar=",", - ), - desc.GroupAttribute( - name="bboxRotation", - label="Euler Rotation", - description="Rotation in Euler degrees.", - groupDesc=[ - desc.FloatParam( - name="x", label="x", description="Euler X rotation.", - value=0.0, - range=(-90.0, 90.0, 1.0) - ), - desc.FloatParam( - name="y", label="y", description="Euler Y rotation.", - value=0.0, - range=(-180.0, 180.0, 1.0) - ), - desc.FloatParam( - name="z", label="z", description="Euler Z rotation.", - value=0.0, - range=(-180.0, 180.0, 1.0) - ), - ], - joinChar=",", - ), - desc.GroupAttribute( - name="bboxScale", - label="Scale", - description="Scale of the bounding box.", - groupDesc=[ - desc.FloatParam( - name="x", label="x", description="X scale.", - value=1.0, - range=(0.0, 20.0, 0.01), - ), - desc.FloatParam( - name="y", label="y", description="Y scale.", - value=1.0, - range=(0.0, 20.0, 0.01), - ), - desc.FloatParam( - name="z", label="z", description="Z scale.", - value=1.0, - range=(0.0, 20.0, 0.01), - ), - ], - joinChar=",", - ), - ], - joinChar=",", - enabled=lambda node: node.useBoundingBox.value, - ), - desc.BoolParam( - name="estimateSpaceFromSfM", - label="Estimate Space From SfM", - description="Estimate the 3D space from the SfM.", - value=True, - advanced=True, - ), - desc.IntParam( - name="estimateSpaceMinObservations", - label="Min Observations For SfM Space Estimation", - description="Minimum number of observations for the space estimation from the SfM.", - value=3, - range=(0, 100, 1), - advanced=True, - enabled=lambda node: node.estimateSpaceFromSfM.value, - ), - desc.FloatParam( - name="estimateSpaceMinObservationAngle", - label="Min Observations Angle For SfM Space Estimation", - description="Minimum angle between two observations for the space estimation from the SfM.", - value=10.0, - range=(0.0, 120.0, 1.0), - enabled=lambda node: node.estimateSpaceFromSfM.value, - ), - desc.IntParam( - name="maxInputPoints", - label="Max Input Points", - description="Maximum input points loaded from depth map images.", - value=50000000, - range=(500000, 500000000, 1000), - ), - desc.IntParam( - name="maxPoints", - label="Max Points", - description="Maximum points at the end of the depth maps fusion.", - value=5000000, - range=(100000, 10000000, 1000), - ), - desc.IntParam( - name="maxPointsPerVoxel", - label="Max Points Per Voxel", - description="Maximum points per voxel.", - value=1000000, - range=(500000, 30000000, 1000), - advanced=True, - ), - desc.IntParam( - name="minStep", - label="Min Step", - description="The step used to load depth values from depth maps is computed from 'maxInputPoints'.\n" - "Here we define the minimum value for this step, so on small datasets we will not spend " - "too much time at the beginning loading all the depth values.", - value=2, - range=(1, 20, 1), - advanced=True, - ), - desc.ChoiceParam( - name="partitioning", - label="Partitioning", - description="Single block or auto partitioning.", - value="singleBlock", - values=["singleBlock", "auto"], - advanced=True, - ), - desc.ChoiceParam( - name="repartition", - label="Repartition", - description="Multi-resolution or regular grid-based repartition.", - value="multiResolution", - values=["multiResolution", "regularGrid"], - advanced=True, - ), - desc.FloatParam( - name="angleFactor", - label="Angle Factor", - description="Angle factor.", - value=15.0, - range=(0.0, 200.0, 1.0), - advanced=True, - ), - desc.FloatParam( - name="simFactor", - label="Sim Factor", - description="Sim factor.", - value=15.0, - range=(0.0, 200.0, 1.0), - advanced=True, - ), - desc.IntParam( - name="minVis", - label="Min Observations", - description="Filter points based on their number of observations.", - value=2, - range=(1, 20, 1), - advanced=True, - ), - desc.FloatParam( - name="pixSizeMarginInitCoef", - label="Pix Size Margin Init Coef", - description="Size of the margin init coefficient, in pixels.", - value=2.0, - range=(0.0, 10.0, 0.1), - advanced=True, - ), - desc.FloatParam( - name="pixSizeMarginFinalCoef", - label="Pix Size Margin Final Coef", - description="Size of the margin final coefficient, in pixels.", - value=4.0, - range=(0.0, 10.0, 0.1), - advanced=True, - ), - desc.FloatParam( - name="voteMarginFactor", - label="Vote Margin Factor", - description="Vote margin factor.", - value=4.0, - range=(0.1, 10.0, 0.1), - advanced=True, - ), - desc.FloatParam( - name="contributeMarginFactor", - label="Contribute Margin Factor", - description="Contribute margin factor.", - value=2.0, - range=(0.0, 10.0, 0.1), - advanced=True, - ), - desc.FloatParam( - name="simGaussianSizeInit", - label="Sim Gaussian Size Init", - description="Sim Gaussian size init.", - value=10.0, - range=(0.0, 50.0, 0.1), - advanced=True, - ), - desc.FloatParam( - name="simGaussianSize", - label="Sim Gaussian Size", - description="Sim Gaussian size.", - value=10.0, - range=(0.0, 50.0, 0.1), - advanced=True, - ), - desc.FloatParam( - name="minAngleThreshold", - label="Min Angle Threshold", - description="Minimum angle threshold.", - value=1.0, - range=(0.0, 10.0, 0.01), - advanced=True, - ), - desc.BoolParam( - name="refineFuse", - label="Refine Fuse", - description="Refine depth map fusion with the new pixels size defined by angle and similarity scores.", - value=True, - advanced=True, - ), - desc.IntParam( - name="helperPointsGridSize", - label="Helper Points Grid Size", - description="Grid size for the helper points.", - value=10, - range=(0, 50, 1), - advanced=True, - ), - desc.BoolParam( - name="densify", - label="Densify", - description="Densify scene with helper points around vertices.", - value=False, - invalidate=False, - advanced=True, - group="", - ), - desc.IntParam( - name="densifyNbFront", - label="Densify: Front", - description="Densify vertices: front.", - value=1, - range=(0, 5, 1), - advanced=True, - enabled=lambda node: node.densify.value, - ), - desc.IntParam( - name="densifyNbBack", - label="Densify: Back", - description="Densify vertices: back.", - value=1, - range=(0, 5, 1), - advanced=True, - enabled=lambda node: node.densify.value, - ), - desc.FloatParam( - name="densifyScale", - label="Densify Scale", - description="Scale between points used to densify the scene.", - value=20.0, - range=(0.0, 10.0, 0.1), - advanced=True, - enabled=lambda node: node.densify.value, - ), - desc.FloatParam( - name="nPixelSizeBehind", - label="Nb Pixel Size Behind", - description="Number of pixel size units to vote behind the vertex as FULL status.", - value=4.0, - range=(0.0, 10.0, 0.1), - advanced=True, - ), - desc.FloatParam( - name="fullWeight", - label="Full Weight", - description="Weighting for full status.", - value=1.0, - range=(0.0, 10.0, 0.1), - advanced=True, - ), - desc.BoolParam( - name="voteFilteringForWeaklySupportedSurfaces", - label="Weakly Supported Surface Support", - description="Improve support of weakly supported surfaces with a tetrahedra fullness score filtering.", - value=True, - ), - desc.BoolParam( - name="addLandmarksToTheDensePointCloud", - label="Add Landmarks To The Dense Point Cloud", - description="Add SfM landmarks to the dense point cloud.", - value=False, - advanced=True, - ), - desc.IntParam( - name="invertTetrahedronBasedOnNeighborsNbIterations", - label="Tretrahedron Neighbors Coherency Nb Iterations", - description="Invert cells status around surface to improve smoothness.\n" - "Set to 0 to disable.", - value=10, - range=(0, 30, 1), - advanced=True, - ), - desc.FloatParam( - name="minSolidAngleRatio", - label="Min Solid Angle Ratio", - description="Change cells status on surface around vertices to improve smoothness using solid angle \n" - "ratio between full/empty parts. Set to 0 to disable.", - value=0.2, - range=(0.0, 0.5, 0.01), - advanced=True, - ), - desc.IntParam( - name="nbSolidAngleFilteringIterations", - label="Nb Solid Angle Filtering Iterations", - description="Filter cells status on surface around vertices to improve smoothness using solid angle ratio \n" - "between full/empty parts. Set to 0 to disable.", - value=2, - range=(0, 30, 1), - advanced=True, - ), - desc.BoolParam( - name="colorizeOutput", - label="Colorize Output", - description="Whether to colorize output dense point cloud and mesh.", - value=False, - ), - desc.BoolParam( - name="addMaskHelperPoints", - label="Add Mask Helper Points", - description="Add Helper points on the outline of the depth maps masks.", - value=False, - invalidate=False, - advanced=True, - group="", - ), - desc.FloatParam( - name="maskHelperPointsWeight", - label="Mask Helper Points Weight", - description="Weight value for mask helper points. 0 means no helper point.", - value=1.0, - range=(0.0, 20.0, 1.0), - advanced=True, - enabled=lambda node: node.addMaskHelperPoints.value, - ), - desc.IntParam( - name="maskBorderSize", - label="Mask Border Size", - description="Number of pixels on mask borders.", - value=4, - range=(0, 20, 1), - advanced=True, - enabled=lambda node: node.addMaskHelperPoints.value, - ), - desc.IntParam( - name="maxNbConnectedHelperPoints", - label="Helper Points: Max Segment Size", - description="Maximum size of a segment of connected helper points before we remove it.\n" - "Small segments of helper points can be on the real surface and should not be removed to avoid the creation of holes.\n" - "0 means that all helper points are removed. -1 means that helper points are not filtered at all.", - value=50, - range=(-1, 100, 1), - advanced=True, - ), - desc.BoolParam( - name="saveRawDensePointCloud", - label="Save Raw Dense Point Cloud", - description="Save dense point cloud before cut and filtering.", - value=False, - invalidate=False, - advanced=True, - ), - desc.BoolParam( - name="exportDebugTetrahedralization", - label="Export Debug Tetrahedralization", - description="Export debug cells score as tetrahedral mesh.\n" - "WARNING: Could create HUGE meshes, only use on very small datasets.", - value=False, - invalidate=False, - advanced=True, - ), - desc.IntParam( - name="seed", - label="Seed", - description="Seed used for random operations.\n" - "0 means use of random device instead of a fixed seed.", - value=0, - range=(0, 10000, 1), - advanced=True, - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="outputMesh", - label="Mesh", - description="Output mesh.", - value="{nodeCacheFolder}/mesh.{outputMeshFileTypeValue}", - ), - desc.File( - name="output", - label="Dense SfMData", - description="Output dense point cloud with visibilities (SfMData file format).", - value="{nodeCacheFolder}/densePointCloud.abc", - ), - ] diff --git a/meshroom/nodes/aliceVision/NodalSfM.py b/meshroom/nodes/aliceVision/NodalSfM.py deleted file mode 100644 index 1dbd902ced..0000000000 --- a/meshroom/nodes/aliceVision/NodalSfM.py +++ /dev/null @@ -1,51 +0,0 @@ -__version__ = "2.0" - -from meshroom.core import desc -from meshroom.core.utils import DESCRIBER_TYPES, VERBOSE_LEVEL - - -class NodalSfM(desc.AVCommandLineNode): - commandLine = 'aliceVision_nodalSfM {allParams}' - size = desc.DynamicNodeSize('input') - - category = 'Sparse Reconstruction' - documentation = ''' -A Structure-From-Motion node specifically designed to handle pure rotation camera movements. -''' - - inputs = [ - desc.File( - name="input", - label="SfMData", - description="Input SfMData file.", - value="", - ), - desc.File( - name="tracksFilename", - label="Tracks File", - description="Input tracks file.", - value="", - ), - desc.File( - name="pairs", - label="Pairs File", - description="Information on pairs.", - value="", - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="output", - label="SfMData", - description="Path to the output SfMData file.", - value="{nodeCacheFolder}/sfm.abc", - ), - ] diff --git a/meshroom/nodes/aliceVision/NormalIntegration.py b/meshroom/nodes/aliceVision/NormalIntegration.py deleted file mode 100644 index 207edd8305..0000000000 --- a/meshroom/nodes/aliceVision/NormalIntegration.py +++ /dev/null @@ -1,52 +0,0 @@ -__version__ = "1.0" - -from meshroom.core import desc -from meshroom.core.utils import VERBOSE_LEVEL - -class NormalIntegration(desc.CommandLineNode): - commandLine = 'aliceVision_normalIntegration {allParams}' - category = 'Photometric Stereo' - documentation = ''' -Evaluate a depth map from a normals map (currently in development) -''' - - inputs = [ - desc.File( - name="inputPath", - label="Normal Maps Folder", - description="Path to the folder containing the normal maps and the masks.", - value="", - ), - desc.File( - name="sfmDataFile", - label="SfMData", - description="Input SfMData file.", - value="", - ), - desc.IntParam( - name="downscale", - label="Downscale Factor", - description="Downscale factor for faster results.", - value=1, - range=(1, 10, 1), - advanced=True, - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="depthMap", - label="Depth Map Camera", - description="Generated depth in the camera coordinate system.", - semantic="image", - value="{nodeCacheFolder}/_depthMap.exr", - group="", # do not export on the command line - ) - ] diff --git a/meshroom/nodes/aliceVision/NormalMapRendering.py b/meshroom/nodes/aliceVision/NormalMapRendering.py deleted file mode 100644 index 7355842f76..0000000000 --- a/meshroom/nodes/aliceVision/NormalMapRendering.py +++ /dev/null @@ -1,52 +0,0 @@ -__version__ = "1.0" - -from meshroom.core import desc -from meshroom.core.utils import VERBOSE_LEVEL - - -class NormalMapRendering(desc.AVCommandLineNode): - commandLine = "aliceVision_normalMapRendering {allParams}" - - category = "Utils" - documentation = """ - Using camera parameters and mesh, render normalmaps for each view - """ - - inputs = [ - desc.File( - name="input", - label="Input SfMData", - description="Input SfMData file.", - value="", - ), - desc.File( - name="mesh", - label="Input Mesh", - description="Input mesh file.", - value="", - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="output", - label="Folder", - description="Output folder.", - value="{nodeCacheFolder}", - ), - desc.File( - name="normal", - label="Normal Maps", - description="Rendered normal maps.", - semantic="image", - value="{nodeCacheFolder}/_normalMap.exr", - group="", # do not export on the command line - ), - ] diff --git a/meshroom/nodes/aliceVision/PanoramaCompositing.py b/meshroom/nodes/aliceVision/PanoramaCompositing.py deleted file mode 100644 index a5ac007aae..0000000000 --- a/meshroom/nodes/aliceVision/PanoramaCompositing.py +++ /dev/null @@ -1,118 +0,0 @@ -__version__ = "2.0" - -import json -import os - -from meshroom.core import desc -from meshroom.core.utils import EXR_STORAGE_DATA_TYPE, VERBOSE_LEVEL - - -class PanoramaCompositing(desc.AVCommandLineNode): - commandLine = 'aliceVision_panoramaCompositing {allParams}' - size = desc.DynamicNodeSize('input') - parallelization = desc.Parallelization(blockSize=5) - commandLineRange = '--rangeIteration {rangeIteration} --rangeSize {rangeBlockSize}' - cpu = desc.Level.INTENSIVE - ram = desc.Level.INTENSIVE - - category = 'Panorama HDR' - documentation = ''' -Once the images have been transformed geometrically (in PanoramaWarping), -they have to be fused together in a single panorama image which looks like a single photography. -The Multi-band Blending method provides the best quality. It averages the pixel values using multiple bands in the frequency domain. -Multiple cameras are contributing to the low frequencies and only the best one contributes to the high frequencies. -''' - - inputs = [ - desc.File( - name="input", - label="Input SfMData", - description="Input SfMData file.", - value="", - ), - desc.File( - name="warpingFolder", - label="Warping Folder", - description="Panorama warping results folder.", - value="", - ), - desc.File( - name="labels", - label="Labels Images", - description="Panorama seams results images.", - value="", - ), - desc.ChoiceParam( - name="compositerType", - label="Compositer Type", - description="Which compositer should be used to blend images:\n" - " - multiband: high quality transition by fusing images by frequency bands.\n" - " - replace: debug option with straight transitions.\n" - " - alpha: debug option with linear transitions.", - value="multiband", - values=["replace", "alpha", "multiband"], - ), - desc.IntParam( - name="forceMinPyramidLevels", - label="Min Pyramid Levels", - description="Force the minimal number of levels in the pyramid for multiband compositer.", - value=0, - range=(0, 16, 1), - enabled=lambda node: node.compositerType.value and node.compositerType.value == "multiband", - ), - desc.IntParam( - name="maxThreads", - label="Max Nb Threads", - description="Specifies the maximum number of threads to run simultaneously.", - value=4, - range=(0, 48, 1), - invalidate=False, - advanced=True, - ), - desc.BoolParam( - name="useTiling", - label="Use Tiling", - description="Enable tiling mode for parallelization.", - value=True, - exposed=True, - ), - desc.ChoiceParam( - name="storageDataType", - label="Storage Data Type", - description="Storage image data type:\n" - " - float: Use full floating point (32 bits per channel).\n" - " - half: Use half float (16 bits per channel).\n" - " - halfFinite: Use half float, but clamp values to avoid non-finite values.\n" - " - auto: Use half float if all values can fit, else use full float.", - values=EXR_STORAGE_DATA_TYPE, - value="float", - ), - desc.ChoiceParam( - name="overlayType", - label="Overlay Type", - description="Overlay on top of panorama to analyze transitions:\n" - " - none: no overlay.\n" - " - borders: display image borders.\n" - " - seams: display transitions between images.\n" - " - all: display borders and seams.", - value="none", - values=["none", "borders", "seams", "all"], - advanced=True, - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="output", - label="Folder", - description="Output folder containing the composited panorama.", - value="{nodeCacheFolder}", - ), - ] diff --git a/meshroom/nodes/aliceVision/PanoramaEstimation.py b/meshroom/nodes/aliceVision/PanoramaEstimation.py deleted file mode 100644 index d041be7e11..0000000000 --- a/meshroom/nodes/aliceVision/PanoramaEstimation.py +++ /dev/null @@ -1,181 +0,0 @@ -__version__ = "1.0" - -import json -import os - -from meshroom.core import desc -from meshroom.core.utils import DESCRIBER_TYPES, VERBOSE_LEVEL - - -class PanoramaEstimation(desc.AVCommandLineNode): - commandLine = 'aliceVision_panoramaEstimation {allParams}' - size = desc.DynamicNodeSize('input') - - category = 'Panorama HDR' - documentation = ''' -Estimate relative camera rotations between input images. -''' - - inputs = [ - desc.File( - name="input", - label="SfMData", - description="Input SfMData file.", - value="", - ), - desc.ListAttribute( - elementDesc=desc.File( - name="featuresFolder", - label="Features Folder", - description="Folder containing some extracted features.", - value="", - ), - name="featuresFolders", - label="Features Folders", - description="Folder(s) containing the extracted features.", - exposed=True, - ), - desc.ListAttribute( - elementDesc=desc.File( - name="matchesFolder", - label="Matches Folder", - description="Folder containing some matches.", - value="", - ), - name="matchesFolders", - label="Matches Folders", - description="Folder(s) in which computed matches are stored.", - ), - desc.ChoiceParam( - name="describerTypes", - label="Describer Types", - description="Describer types used to describe an image.", - values=DESCRIBER_TYPES, - value=["sift"], - exclusive=False, - joinChar=",", - exposed=True, - ), - desc.FloatParam( - name="offsetLongitude", - label="Longitude Offset", - description="Offset to the panorama longitude (in degrees).", - value=0.0, - range=(-180.0, 180.0, 1.0), - ), - desc.FloatParam( - name="offsetLatitude", - label="Latitude Offset", - description="Offset to the panorama latitude (in degrees).", - value=0.0, - range=(-90.0, 90.0, 1.0), - ), - desc.ChoiceParam( - name="rotationAveraging", - label="Rotation Averaging Method", - description="Method for rotation averaging :\n" - " - L1 minimization\n" - " - L2 minimization", - values=["L1_minimization", "L2_minimization"], - value="L2_minimization", - advanced=True, - ), - desc.ChoiceParam( - name="relativeRotation", - label="Relative Rotation Method", - description="Method for relative rotation :\n" - " - from essential matrix\n" - " - from homography matrix\n" - " - from rotation matrix", - values=["essential_matrix", "homography_matrix", "rotation_matrix"], - value="rotation_matrix", - advanced=True, - ), - desc.BoolParam( - name="rotationAveragingWeighting", - label="Rotation Averaging Weighting", - description="Rotation averaging weighting based on the number of feature matches.", - value=True, - advanced=True, - ), - desc.BoolParam( - name="filterMatches", - label="Filter Matches", - description="Filter the matches.", - value=False, - ), - desc.BoolParam( - name="refine", - label="Refine", - description="Refine camera relative poses, points and optionally internal camera parameters.", - value=True, - ), - desc.BoolParam( - name="lockAllIntrinsics", - label="Lock All Intrinsics", - description="Force to keep all the intrinsics parameters of the cameras (focal length, \n" - "principal point, distortion if any) constant during the reconstruction.\n" - "This may be helpful if the input cameras are already fully calibrated.", - value=False, - ), - desc.FloatParam( - name="maxAngleToPrior", - label="Max Angle To Priors (deg.)", - description="Maximum angle allowed regarding the input prior (in degrees) before refinement.", - value=20.0, - range=(0.0, 360.0, 1.0), - advanced=True, - ), - desc.FloatParam( - name="maxAngleToPriorRefined", - label="Max Refined Angle To Priors (deg.)", - description="Maximum angle allowed regarding the input prior (in degrees) after refinement.", - value=2.0, - range=(0.0, 360.0, 1.0), - advanced=True, - ), - desc.FloatParam( - name="maxAngularError", - label="Max Angular Error (deg.)", - description="Maximum angular error in global rotation averging (in degrees).", - value=100.0, - range=(0.0, 360.0, 1.0), - advanced=True, - ), - desc.BoolParam( - name="intermediateRefineWithFocal", - label="Intermediate Refine: Focal", - description="Intermediate refine with rotation and focal length only.", - value=False, - advanced=True, - ), - desc.BoolParam( - name="intermediateRefineWithFocalDist", - label="Intermediate Refine: Focal And Distortion", - description="Intermediate refine with rotation, focal length and distortion.", - value=False, - advanced=True, - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="output", - label="SfM File", - description="Path to the output SfM file.", - value="{nodeCacheFolder}/panorama.abc", - ), - desc.File( - name="outputViewsAndPoses", - label="Views And Poses", - description="Path to the output SfMData file with cameras (views and poses).", - value="{nodeCacheFolder}/cameras.sfm", - ), - ] diff --git a/meshroom/nodes/aliceVision/PanoramaInit.py b/meshroom/nodes/aliceVision/PanoramaInit.py deleted file mode 100644 index a1bf735882..0000000000 --- a/meshroom/nodes/aliceVision/PanoramaInit.py +++ /dev/null @@ -1,160 +0,0 @@ -__version__ = "2.0" - -from meshroom.core import desc -from meshroom.core.utils import VERBOSE_LEVEL - - -class PanoramaInit(desc.AVCommandLineNode): - commandLine = 'aliceVision_panoramaInit {allParams}' - size = desc.DynamicNodeSize('input') - - category = 'Panorama HDR' - documentation = ''' -This node allows to setup the Panorama: - -1/ Enables the initialization the cameras from known position in an XML file (provided by -["Roundshot VR Drive"](https://www.roundshot.com/xml_1/internet/fr/application/d394/d395/f396.cfm) ). - -2/ Enables to setup Full Fisheye Optics (to use an Equirectangular camera model). - -3/ To automatically detects the Fisheye Circle (radius + center) in input images or manually adjust it. - -''' - - inputs = [ - desc.File( - name="input", - label="SfMData", - description="Input SfMData file.", - value="", - ), - desc.ChoiceParam( - name="initializeCameras", - label="Initialize Cameras", - description="Initialize cameras.", - value="No", - values=["No", "File", "Horizontal", "Horizontal+Zenith", "Zenith+Horizontal", "Spherical"], - ), - desc.File( - name="config", - label="XML Config", - description="XML data file.", - value="", - enabled=lambda node: node.initializeCameras.value == "File", - ), - desc.BoolParam( - name="yawCW", - label="Yaw CW", - description="If selected, the yaw rotation will be clockwise. Otherwise, it will be counter-clockwise.", - value=True, - enabled=lambda node: ("Horizontal" in node.initializeCameras.value) or (node.initializeCameras.value == "Spherical"), - ), - desc.BoolParam( - name="buildContactSheet", - label="Build Contact Sheet", - description="Build the contact sheet for the panorama if an XML data file is provided.\n" - "The contact sheet consists in a preview of the panorama using the input images.", - value=True, - enabled=lambda node: node.config.enabled and node.config.value != "", - ), - desc.ListAttribute( - elementDesc=desc.IntParam( - name="nbViews", - label="Number of Views", - description="Number of views for a line.", - value=-1, - range=(-1, 20, 1), - ), - name="nbViewsPerLine", - label="Spherical: Nb Views Per Line", - description="Number of views per line in Spherical acquisition.\n" - "Assumes angles from [-90,+90deg] for pitch and [-180,+180deg] for yaw.\n" - "Use -1 to estimate the number of images automatically.", - joinChar=",", - enabled=lambda node: node.initializeCameras.value == "Spherical", - ), - desc.BoolParam( - name="useFisheye", - label="Full Fisheye", - description="Set this option to declare a full fisheye panorama setup.", - value=False, - ), - desc.BoolParam( - name="estimateFisheyeCircle", - label="Estimate Fisheye Circle", - description="Automatically estimate the fisheye circle center and radius instead of using user values.", - value=True, - enabled=lambda node: node.useFisheye.value, - ), - desc.GroupAttribute( - name="fisheyeCenterOffset", - label="Fisheye Center", - description="Center of the fisheye circle (XY offset to the center in pixels).", - groupDesc=[ - desc.FloatParam( - name="fisheyeCenterOffset_x", - label="x", - description="X offset in pixels.", - value=0.0, - range=(-1000.0, 10000.0, 1.0), - ), - desc.FloatParam( - name="fisheyeCenterOffset_y", - label="y", - description="Y offset in pixels.", - value=0.0, - range=(-1000.0, 10000.0, 1.0), - ), - ], - group=None, # skip group from command line - enabled=lambda node: node.useFisheye.value and not node.estimateFisheyeCircle.value, - ), - desc.FloatParam( - name="fisheyeRadius", - label="Fisheye Radius", - description="Fisheye visibillity circle radius (in % of image's shortest side).", - value=96.0, - range=(0.0, 150.0, 0.01), - enabled=lambda node: node.useFisheye.value and not node.estimateFisheyeCircle.value, - ), - desc.ChoiceParam( - name="inputAngle", - label="Input Angle Offset", - description="Add a rotation to the input XML given poses (CCW).", - value="None", - values=["None", "rotate90", "rotate180", "rotate270"], - ), - desc.BoolParam( - name="debugFisheyeCircleEstimation", - label="Debug Fisheye Circle Detection", - description="Debug fisheye circle detection.", - value=False, - enabled=lambda node: node.useFisheye.value, - advanced=True, - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="contactSheet", - label="Contact sheet", - semantic="image", - description="Contact sheet path.", - value="{nodeCacheFolder}/contactSheetImage.jpg", - group="", # do not export on the command line - enabled=lambda node: node.buildContactSheet.enabled - ), - desc.File( - name="outSfMData", - label="SfMData File", - description="Path to the output SfMData file.", - value="{nodeCacheFolder}/sfmData.sfm", - ), - ] diff --git a/meshroom/nodes/aliceVision/PanoramaMerging.py b/meshroom/nodes/aliceVision/PanoramaMerging.py deleted file mode 100644 index 413f1f27d0..0000000000 --- a/meshroom/nodes/aliceVision/PanoramaMerging.py +++ /dev/null @@ -1,77 +0,0 @@ -__version__ = "1.0" - -import json -import os - -from meshroom.core import desc -from meshroom.core.utils import EXR_STORAGE_DATA_TYPE, VERBOSE_LEVEL - - -class PanoramaMerging(desc.AVCommandLineNode): - commandLine = 'aliceVision_panoramaMerging {allParams}' - size = desc.DynamicNodeSize('input') - cpu = desc.Level.NORMAL - ram = desc.Level.INTENSIVE - - category = 'Panorama HDR' - documentation = ''' -Merge all inputs coming from the PanoramaCompositing node. -''' - - inputs = [ - desc.File( - name="input", - label="Input SfMData", - description="Input SfMData file.", - value="", - ), - desc.File( - name="compositingFolder", - label="Compositing Folder", - description="Panorama compositing results.", - value="", - ), - desc.ChoiceParam( - name="outputFileType", - label="Output File Type", - description="Output file type for the merged panorama.", - value="exr", - values=["jpg", "png", "tif", "exr"], - group="", # not part of allParams, as this is not a parameter for the command line - ), - desc.BoolParam( - name="useTiling", - label="Use Tiling", - description="Enable tiling mode for parallelization.", - value=True, - exposed=True, - ), - desc.ChoiceParam( - name="storageDataType", - label="Storage Data Type", - description="Storage image data type:\n" - " - float: Use full floating point (32 bits per channel).\n" - " - half: Use half float (16 bits per channel).\n" - " - halfFinite: Use half float, but clamp values to avoid non-finite values.\n" - " - auto: Use half float if all values can fit, else use full float.\n", - values=EXR_STORAGE_DATA_TYPE, - value="float", - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="outputPanorama", - label="Panorama", - description="Output merged panorama image.", - semantic="image", - value="{nodeCacheFolder}/panorama.{outputFileTypeValue}", - ), - ] diff --git a/meshroom/nodes/aliceVision/PanoramaPostProcessing.py b/meshroom/nodes/aliceVision/PanoramaPostProcessing.py deleted file mode 100644 index 1a0a8a4aba..0000000000 --- a/meshroom/nodes/aliceVision/PanoramaPostProcessing.py +++ /dev/null @@ -1,126 +0,0 @@ -__version__ = "2.0" - -import json -import os - -from meshroom.core import desc -from meshroom.core.utils import COLORSPACES, VERBOSE_LEVEL - - -class PanoramaPostProcessing(desc.CommandLineNode): - commandLine = 'aliceVision_panoramaPostProcessing {allParams}' - cpu = desc.Level.NORMAL - ram = desc.Level.INTENSIVE - - category = 'Panorama HDR' - documentation = ''' -Post process the panorama. -''' - - inputs = [ - desc.File( - name="inputPanorama", - label="Input Panorama", - description="Input panorama image.", - value="", - ), - desc.BoolParam( - name="fillHoles", - label="Fill Holes Algorithm", - description="Fill the non attributed pixels with push pull algorithm if set.", - value=False, - ), - desc.BoolParam( - name="exportLevels", - label="Export Downscaled Levels", - description="Export downscaled panorama levels.", - value=False, - ), - desc.IntParam( - name="lastLevelMaxSize", - label="Last Level Max Size", - description="Maximum width of smallest downscaled panorama level.", - value=3840, - range=(1, 100000), - ), - desc.IntParam( - name="previewSize", - label="Panorama Preview Width", - description="The width (in pixels) of the output panorama preview.", - value=1000, - range=(0, 5000, 100), - ), - desc.ChoiceParam( - name="outputColorSpace", - label="Output Color Space", - description="The color space of the output image.", - values=COLORSPACES, - value="Linear", - ), - desc.ChoiceParam( - name="compressionMethod", - label="Compression Method", - description="Compression method for output EXR image.", - value="auto", - values=["none", "auto", "rle", "zip", "zips", "piz", "pxr24", "b44", "b44a", "dwaa", "dwab"], - ), - desc.IntParam( - name="compressionLevel", - label="Compression Level", - description="Level of compression for the output EXR image. The range depends on method used.\n" - "For zip/zips methods, values must be between 1 and 9.\n" - "A value of 0 will be ignored, default value for the selected method will be used.", - value=0, - range=(0, 500, 1), - enabled=lambda node: node.compressionMethod.value in ["dwaa", "dwab", "zip", "zips"], - ), - desc.StringParam( - name="panoramaName", - label="Output Panorama Name", - description="Name of the output panorama.", - value="panorama.exr", - invalidate=False, - group=None, - advanced=True, - ), - desc.StringParam( - name="previewName", - label="Panorama Preview Name", - description="Name of the preview of the output panorama.", - value="panoramaPreview.jpg", - invalidate=False, - group=None, - advanced=True, - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="outputPanoramaPreview", - label="Output Panorama Preview", - description="Preview of the generated panorama in JPG format.", - semantic="image", - value=lambda attr: "{nodeCacheFolder}/" + attr.node.previewName.value, - ), - desc.File( - name="outputPanorama", - label="Output Panorama", - description="Generated panorama in EXR format.", - semantic="image", - value=lambda attr: "{nodeCacheFolder}/" + attr.node.panoramaName.value, - ), - desc.File( - name="downscaledPanoramaLevels", - label="Downscaled Panorama Levels", - description="Downscaled versions of the generated panorama.", - value=lambda attr: "{nodeCacheFolder}/" + os.path.splitext(attr.node.panoramaName.value)[0] + "_level_*.exr", - group="", - ), - ] diff --git a/meshroom/nodes/aliceVision/PanoramaPrepareImages.py b/meshroom/nodes/aliceVision/PanoramaPrepareImages.py deleted file mode 100644 index 6a4f6137dc..0000000000 --- a/meshroom/nodes/aliceVision/PanoramaPrepareImages.py +++ /dev/null @@ -1,41 +0,0 @@ -__version__ = "1.1" - -from meshroom.core import desc -from meshroom.core.utils import VERBOSE_LEVEL - -import os.path - - -class PanoramaPrepareImages(desc.AVCommandLineNode): - commandLine = 'aliceVision_panoramaPrepareImages {allParams}' - size = desc.DynamicNodeSize('input') - - category = 'Panorama HDR' - documentation = ''' -Prepare images for Panorama pipeline: ensures that images orientations are coherent. -''' - - inputs = [ - desc.File( - name="input", - label="Input", - description="SfMData file.", - value="", - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="output", - label="SfMData", - description="Output SfMData file.", - value=lambda attr: "{nodeCacheFolder}/" + os.path.basename(attr.node.input.value), - ), - ] diff --git a/meshroom/nodes/aliceVision/PanoramaSeams.py b/meshroom/nodes/aliceVision/PanoramaSeams.py deleted file mode 100644 index ffadc05843..0000000000 --- a/meshroom/nodes/aliceVision/PanoramaSeams.py +++ /dev/null @@ -1,70 +0,0 @@ -__version__ = "2.0" - -import json -import os - -from meshroom.core import desc -from meshroom.core.utils import VERBOSE_LEVEL - - -class PanoramaSeams(desc.AVCommandLineNode): - commandLine = 'aliceVision_panoramaSeams {allParams}' - size = desc.DynamicNodeSize('input') - cpu = desc.Level.INTENSIVE - ram = desc.Level.INTENSIVE - - category = 'Panorama HDR' - documentation = ''' -Estimate the seams lines between the inputs to provide an optimal compositing in a further node -''' - - inputs = [ - desc.File( - name="input", - label="Input SfMData", - description="Input SfMData file.", - value="", - ), - desc.File( - name="warpingFolder", - label="Warping Folder", - description="Panorama warping results.", - value="", - ), - desc.IntParam( - name="maxWidth", - label="Max Resolution", - description="Maximal resolution for the panorama seams estimation.", - value=5000, - range=(0, 100000, 1), - ), - desc.BoolParam( - name="useGraphCut", - label="Use Smart Seams", - description="Use a graphcut algorithm to optimize seams for better transitions between images.", - value=True, - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="output", - label="Labels", - description="", - semantic="image", - value="{nodeCacheFolder}/labels.exr", - ), - desc.File( - name="outputSfm", - label="Output SfMData File", - description="Path to the output SfMData file.", - value="{nodeCacheFolder}/panorama.sfm", - ), - ] diff --git a/meshroom/nodes/aliceVision/PanoramaWarping.py b/meshroom/nodes/aliceVision/PanoramaWarping.py deleted file mode 100644 index 2a4a062689..0000000000 --- a/meshroom/nodes/aliceVision/PanoramaWarping.py +++ /dev/null @@ -1,98 +0,0 @@ -__version__ = "1.1" - -import json -import os - -from meshroom.core import desc -from meshroom.core.utils import COLORSPACES, EXR_STORAGE_DATA_TYPE, VERBOSE_LEVEL - - -class PanoramaWarping(desc.AVCommandLineNode): - commandLine = 'aliceVision_panoramaWarping {allParams}' - size = desc.DynamicNodeSize('input') - parallelization = desc.Parallelization(blockSize=5) - commandLineRange = '--rangeStart {rangeStart} --rangeSize {rangeBlockSize}' - - category = 'Panorama HDR' - documentation = ''' -Compute the image warping for each input image in the panorama coordinate system. -''' - - inputs = [ - desc.File( - name="input", - label="SfMData", - description="Input SfMData file.", - value="", - ), - desc.BoolParam( - name="estimateResolution", - label="Estimate Resolution", - description="Estimate output panorama resolution automatically based on the resolution of input images.", - value=True, - group=None, # skip group from command line - ), - desc.IntParam( - name="panoramaWidth", - label="Panorama Width", - description="Choose the output panorama width (in pixels).", - value=10000, - range=(0, 50000, 1000), - enabled=lambda node: (not node.estimateResolution.value), - ), - desc.IntParam( - name="percentUpscale", - label="Upscale Ratio", - description="Percentage of upscaled pixels.\n" - "\n" - "How many percent of the pixels will be upscaled (compared to its original resolution):\n" - " - 0: all pixels will be downscaled.\n" - " - 50: on average, the input resolution is kept (optimal to reduce over/under-sampling).\n" - " - 100: all pixels will be upscaled.\n", - value=50, - range=(0, 100, 1), - enabled=lambda node: (node.estimateResolution.value), - ), - desc.IntParam( - name="maxPanoramaWidth", - label="Max Panorama Width", - description="Choose the maximum width for the output panorama (in pixels). 0 means no limit.", - value=70000, - range=(0, 100000, 1000), - enabled=lambda node: (node.estimateResolution.value), - ), - desc.ChoiceParam( - name="workingColorSpace", - label="Working Color Space", - description="Colorspace in which the panorama warping will be performed.", - values=COLORSPACES, - value="Linear", - ), - desc.ChoiceParam( - name="storageDataType", - label="Storage Data Type", - description="Storage image data type:\n" - " - float: Use full floating point (32 bits per channel).\n" - " - half: Use half float (16 bits per channel).\n" - " - halfFinite: Use half float, but clamp values to avoid non-finite values.\n" - " - auto: Use half float if all values can fit, else use full float.", - values=EXR_STORAGE_DATA_TYPE, - value="float", - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="output", - label="Folder", - description="Output folder.", - value="{nodeCacheFolder}", - ), - ] diff --git a/meshroom/nodes/aliceVision/PhotometricStereo.py b/meshroom/nodes/aliceVision/PhotometricStereo.py deleted file mode 100644 index 6ca877e8e9..0000000000 --- a/meshroom/nodes/aliceVision/PhotometricStereo.py +++ /dev/null @@ -1,140 +0,0 @@ -__version__ = "1.0" - -from meshroom.core import desc -from meshroom.core.utils import VERBOSE_LEVEL - -class PhotometricStereo(desc.CommandLineNode): - commandLine = 'aliceVision_photometricStereo {allParams}' - category = 'Photometric Stereo' - documentation = ''' -Reconstruction using Photometric Stereo. A normal map is evaluated from several photographs taken from the same point of view, but under different lighting conditions. -The lighting conditions are assumed to be known. -''' - - inputs = [ - desc.File( - name="inputPath", - label="SfMData", - description="Input SfMData file.", - value="", - ), - desc.File( - name="pathToJSONLightFile", - label="Light File", - description="Path to a JSON file containing the lighting information.\n" - "If empty, .txt files are expected in the image folder.", - value="defaultJSON.txt", - ), - desc.File( - name="maskPath", - label="Mask Folder Path", - description="Path to a folder containing masks or to a mask directly.", - value="", - ), - desc.ChoiceParam( - name="SHOrder", - label="Spherical Harmonics Order", - description="Order of the spherical harmonics:\n" - " - 0: directional.\n" - " - 1: directional + ambient.\n" - " - 2: second order spherical harmonics.", - values=["0", "1", "2"], - value="0", - advanced=True, - ), - desc.BoolParam( - name="removeAmbient", - label="Remove Ambient Light", - description="True if the ambient light is to be removed on the PS images, false otherwise.", - value=False, - advanced=True, - ), - desc.BoolParam( - name="isRobust", - label="Use Robust Algorithm", - description="True to use the robust algorithm, false otherwise.", - value=False, - advanced=True, - ), - desc.IntParam( - name="downscale", - label="Downscale Factor", - description="Downscale factor for faster results.", - value=1, - range=(1, 10, 1), - advanced=True, - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="outputPath", - label="Output Folder", - description="Path to the output folder.", - value="{nodeCacheFolder}", - ), - desc.File( - name="outputSfmDataAlbedo", - label="SfMData Albedo", - description="Output SfMData file containing the albedo information.", - value="{nodeCacheFolder}/albedoMaps.sfm", - group="", # remove from command line - ), - desc.File( - name="outputSfmDataNormal", - label="SfMData Normal", - description="Output SfMData file containing the normal maps information.", - value="{nodeCacheFolder}/normalMaps.sfm", - group="", # remove from command line - ), - desc.File( - name="outputSfmDataNormalPNG", - label="SfMData Normal PNG", - description="Output SfMData file containing the normal maps information.", - value="{nodeCacheFolder}/normalMapsPNG.sfm", - group="", # remove from command line - ), - # these attributes are only here to describe more accurately the output of the node - # by specifying that it generates 2 sequences of images - # (see in Viewer2D.qml how these attributes can be used) - desc.File( - name="normals", - label="Normal Maps Camera", - description="Generated normal maps in the camera coordinate system.", - semantic="image", - value="{nodeCacheFolder}/_normals.exr", - group="", # do not export on the command line - ), - desc.File( - name="normalsPNG", - label="Normal Maps Camera (in false colors)", - description="Generated normal maps in the camera coordinate system (in false colors).", - semantic="image", - value="{nodeCacheFolder}/_normals.png", - group="", # do not export on the command line - ), - desc.File( - name="normalsWorld", - label="Normal Maps World", - description="Generated normal maps in the world coordinate system.", - semantic="image", - value="{nodeCacheFolder}/_normals_w.exr", - group="", # do not export on the command line - ), - - desc.File( - name="albedo", - label="Albedo Maps", - description="Generated albedo maps.", - semantic="image", - value="{nodeCacheFolder}/_albedo.png", - group="", # do not export on the command line - ), - ] diff --git a/meshroom/nodes/aliceVision/PrepareDenseScene.py b/meshroom/nodes/aliceVision/PrepareDenseScene.py deleted file mode 100644 index 87eb78bc20..0000000000 --- a/meshroom/nodes/aliceVision/PrepareDenseScene.py +++ /dev/null @@ -1,108 +0,0 @@ -__version__ = "3.1" - -from meshroom.core import desc -from meshroom.core.utils import VERBOSE_LEVEL - - -class PrepareDenseScene(desc.AVCommandLineNode): - commandLine = 'aliceVision_prepareDenseScene {allParams}' - size = desc.DynamicNodeSize('input') - parallelization = desc.Parallelization(blockSize=40) - commandLineRange = '--rangeStart {rangeStart} --rangeSize {rangeBlockSize}' - - category = 'Dense Reconstruction' - documentation = ''' -This node export undistorted images so the depth map and texturing can be computed on Pinhole images without distortion. -''' - - inputs = [ - desc.File( - name="input", - label="SfMData", - description="Input SfMData file.", - value="", - ), - desc.ListAttribute( - elementDesc=desc.File( - name="imagesFolder", - label="Images Folder", - description="", - value="", - ), - name="imagesFolders", - label="Images Folders", - description="Use images from specific folder(s). Filename should be the same or the image UID.", - ), - desc.ListAttribute( - elementDesc=desc.File( - name="masksFolder", - label="Masks Folder", - description="", - value="", - ), - name="masksFolders", - label="Masks Folders", - description="Use masks from specific folder(s). Filename should be the same or the image UID.", - ), - desc.ChoiceParam( - name="maskExtension", - label="Mask Extension", - description="File extension for the masks to use.", - value="png", - values=["exr", "jpg", "png"], - ), - desc.ChoiceParam( - name="outputFileType", - label="Output File Type", - description="Output file type for the undistorted images.", - value="exr", - values=["jpg", "png", "tif", "exr"], - advanced=True, - ), - desc.BoolParam( - name="saveMetadata", - label="Save Metadata", - description="Save projections and intrinsics information in images metadata (only for .exr images).", - value=True, - advanced=True, - ), - desc.BoolParam( - name="saveMatricesTxtFiles", - label="Save Matrices Text Files", - description="Save projections and intrinsics information in text files.", - value=False, - advanced=True, - ), - desc.BoolParam( - name="evCorrection", - label="Correct Images Exposure", - description="Apply a correction on images' exposure value.", - value=False, - advanced=True, - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="output", - label="Images Folder", - description="Output folder.", - value="{nodeCacheFolder}", - ), - desc.File( - name="undistorted", - label="Undistorted Images", - description="List of undistorted images.", - semantic="image", - value="{nodeCacheFolder}/.{outputFileTypeValue}", - group="", - advanced=True, - ), - ] diff --git a/meshroom/nodes/aliceVision/RelativePoseEstimating.py b/meshroom/nodes/aliceVision/RelativePoseEstimating.py deleted file mode 100644 index b49eb3ced8..0000000000 --- a/meshroom/nodes/aliceVision/RelativePoseEstimating.py +++ /dev/null @@ -1,69 +0,0 @@ -__version__ = "3.0" - -from meshroom.core import desc -from meshroom.core.utils import DESCRIBER_TYPES, VERBOSE_LEVEL - -class RelativePoseEstimating(desc.AVCommandLineNode): - commandLine = 'aliceVision_relativePoseEstimating {allParams}' - size = desc.DynamicNodeSize('input') - - parallelization = desc.Parallelization(blockSize=25) - commandLineRange = '--rangeStart {rangeStart} --rangeSize {rangeBlockSize}' - - category = 'Sparse Reconstruction' - documentation = ''' -Estimate relative pose between each pair of views that share tracks. -''' - - inputs = [ - desc.File( - name="input", - label="SfMData", - description="SfMData file.", - value="", - ), - desc.File( - name="tracksFilename", - label="Tracks File", - description="Tracks file.", - value="", - ), - desc.BoolParam( - name="enforcePureRotation", - label="Enforce pure rotation", - description="Enforce pure rotation as a model", - value=False, - ), - desc.IntParam( - name="countIterations", - label="Ransac Max Iterations", - description="Maximal number of iterations.", - value=1024, - range=(1024, 500000, 1), - advanced=True, - ), - desc.IntParam( - name="minInliers", - label="Ransac Min Inliers", - description="Minimal allowed inliers in two view relationship.", - value=35, - range=(1, 1000, 1), - advanced=True, - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="output", - label="Pairs Info", - description="Path to the output Pairs info files directory.", - value="{nodeCacheFolder}", - ), - ] diff --git a/meshroom/nodes/aliceVision/SelectConnectedViews.py b/meshroom/nodes/aliceVision/SelectConnectedViews.py deleted file mode 100644 index 3db36f8062..0000000000 --- a/meshroom/nodes/aliceVision/SelectConnectedViews.py +++ /dev/null @@ -1,64 +0,0 @@ -__version__ = "1.0" - -from meshroom.core import desc -from meshroom.core.utils import VERBOSE_LEVEL - - -class SelectConnectedViews(desc.AVCommandLineNode): - commandLine = 'aliceVision_selectConnectedViews {allParams}' - - cpu = desc.Level.NORMAL - ram = desc.Level.NORMAL - - category = 'Dense Reconstruction' - documentation = ''' -Select Connected Views based on SfM landmarks. -''' - - inputs = [ - desc.File( - name="input", - label="SfMData", - description="Input SfMData file.", - value="", - ), - desc.IntParam( - name="maxTCams", - label="Max Nb Neighbour Cameras", - description="Maximum number of neighbour cameras per image.", - value=10, - range=(1, 20, 1), - ), - desc.FloatParam( - name="minViewAngle", - label="Min View Angle", - description="Minimum angle between two views (select the neighbouring cameras, select depth planes from epipolar segment point).", - value=2.0, - range=(0.0, 10.0, 0.1), - advanced=True, - ), - desc.FloatParam( - name="maxViewAngle", - label="Max View Angle", - description="Maximum angle between two views (select the neighbouring cameras, select depth planes from epipolar segment point).", - value=70.0, - range=(10.0, 120.0, 1.0), - advanced=True, - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="output", - label="Connected Views", - description="List of connected views in a text file.", - value="{nodeCacheFolder}/connectedViews.txt", - ), - ] diff --git a/meshroom/nodes/aliceVision/SfMAlignment.py b/meshroom/nodes/aliceVision/SfMAlignment.py deleted file mode 100644 index 436ab2a911..0000000000 --- a/meshroom/nodes/aliceVision/SfMAlignment.py +++ /dev/null @@ -1,118 +0,0 @@ -__version__ = "2.0" - -from meshroom.core import desc -from meshroom.core.utils import VERBOSE_LEVEL - -import os.path - - -class SfMAlignment(desc.AVCommandLineNode): - commandLine = 'aliceVision_sfmAlignment {allParams}' - size = desc.DynamicNodeSize('input') - - category = 'Utils' - documentation = ''' -This node allows to change the coordinate system of one SfM scene to align it on another one. - -The alignment can be based on: - * from_cameras_viewid: Align cameras in both SfM on the specified viewId - * from_cameras_poseid: Align cameras in both SfM on the specified poseId - * from_cameras_filepath: Align cameras with a filepath matching, using 'fileMatchingPattern' - * from_cameras_metadata: Align cameras with matching metadata, using 'metadataMatchingList' - * from_markers: Align from markers with the same Id - -''' - - inputs = [ - desc.File( - name="input", - label="Input", - description="Input SfMData file .", - value="", - ), - desc.File( - name="reference", - label="Reference", - description="Path to the scene used as the reference coordinate system.", - value="", - ), - desc.ChoiceParam( - name="method", - label="Alignment Method", - description="Alignment method:\n" - " - from_cameras_viewid: Align cameras with same view ID.\n" - " - from_cameras_poseid: Align cameras with same pose ID.\n" - " - from_cameras_filepath: Align cameras with a filepath matching, using 'fileMatchingPattern'.\n" - " - from_cameras_metadata: Align cameras with matching metadata, using 'metadataMatchingList'.\n" - " - from_markers: Align from markers with the same ID.\n" - " - from_landmarks: Align from matched features.\n", - value="from_cameras_viewid", - values=["from_cameras_viewid", "from_cameras_poseid", "from_cameras_filepath", "from_cameras_metadata", "from_markers", 'from_landmarks'], - ), - desc.StringParam( - name="fileMatchingPattern", - label="File Matching Pattern", - description="Matching regular expression for the 'from_cameras_filepath' method.\n" - "You should capture specific parts of the filepath with parentheses to define matching elements.\n" - "Some examples of patterns:\n" - " - Match the filename without extension (default value): " - r'".*\/(.*?)\.\w{3}"' + "\n" - " - Match the filename suffix after '_': " - r'".*\/.*(_.*?\.\w{3})"' + "\n" - " - Match the filename prefix before '_': " - r'".*\/(.*?)_.*\.\w{3}"', - value=r".*\/(.*?)\.\w{3}", - ), - desc.ListAttribute( - elementDesc=desc.File( - name="metadataMatching", - label="Metadata", - description="", - value="Metadata that should match to create the correspondences.", - ), - name="metadataMatchingList", - label="Metadata Matching List", - description="List of metadata that should match to create the correspondences.\n" - "If the list is empty, the default value will be used: ['Make', 'Model', 'Exif:BodySerialNumber', 'Exif:LensSerialNumber'].", - ), - desc.BoolParam( - name="applyScale", - label="Scale", - description="Apply scale transformation.", - value=True, - ), - desc.BoolParam( - name="applyRotation", - label="Rotation", - description="Apply rotation transformation.", - value=True, - ), - desc.BoolParam( - name="applyTranslation", - label="Translation", - description="Apply translation transformation.", - value=True, - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="output", - label="SfMData File", - description="Output SfMData file.", - value=lambda attr: "{nodeCacheFolder}/" + (os.path.splitext(os.path.basename(attr.node.input.value))[0] or "sfmData") + ".abc", - ), - desc.File( - name="outputViewsAndPoses", - label="Poses", - description="Path to the output SfMData file with cameras (views and poses).", - value="{nodeCacheFolder}/cameras.sfm", - ), - ] diff --git a/meshroom/nodes/aliceVision/SfMChecking.py b/meshroom/nodes/aliceVision/SfMChecking.py deleted file mode 100644 index 2e160bba42..0000000000 --- a/meshroom/nodes/aliceVision/SfMChecking.py +++ /dev/null @@ -1,77 +0,0 @@ -__version__ = "1.0" - -from meshroom.core import desc -from meshroom.core.utils import VERBOSE_LEVEL - - -class SfMChecking(desc.Node): - - category = "Utils" - documentation = """ - Check an input SfM for validity. - Throw an error if the SfM does not satisfy constraints. - """ - - inputs = [ - desc.File( - name="input", - label="SfMData", - description="Input SfMData file.", - value="", - ), - desc.FloatParam( - name="poseCompletion", - label="Completion Percentage", - description="Minimal percent of the views reconstructed.", - value=80.0, - range=(0.0, 100.0, 1.0), - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ) - ] - - outputs = [ - desc.File( - name="output", - label="SfM File", - description="Path to the output SfM file.", - value="{nodeCacheFolder}/sfmData.abc", - ) - ] - - def processChunk(self, chunk): - from pyalicevision import sfmData as avsfmdata - from pyalicevision import sfmDataIO as avsfmdataio - - chunk.logManager.start(chunk.node.verboseLevel.value) - chunk.logger.info("Open input file") - - data = avsfmdata.SfMData() - ret = avsfmdataio.load(data, chunk.node.input.value, avsfmdataio.ALL) - if not ret: - chunk.logger.error("Cannot open input") - chunk.logManager.end() - raise RuntimeError() - - total = len(data.getViews()) - valid = len(data.getValidViews()) - ratio = (100.0 * float(valid)) / float(total) - - chunk.logger.info(f"Total views: {total}") - chunk.logger.info(f"Reconstructed views: {valid}") - chunk.logger.info(f"Percentage of reconstructed views: {ratio}") - - if ratio < chunk.node.poseCompletion.value: - chunk.logger.error("Percentage of reconstructed views is insufficient.") - chunk.logger.error(f"Expected {chunk.node.poseCompletion.value}, got {ratio}.") - chunk.logManager.end() - raise RuntimeError() - - avsfmdataio.save(data, chunk.node.output.value, avsfmdataio.ALL) - - chunk.logManager.end() diff --git a/meshroom/nodes/aliceVision/SfMColorizing.py b/meshroom/nodes/aliceVision/SfMColorizing.py deleted file mode 100644 index bf74217145..0000000000 --- a/meshroom/nodes/aliceVision/SfMColorizing.py +++ /dev/null @@ -1,41 +0,0 @@ -__version__ = "1.0" - -from meshroom.core import desc -from meshroom.core.utils import VERBOSE_LEVEL - -import json - -class SfMColorizing(desc.AVCommandLineNode): - - commandLine = "aliceVision_sfmColorizing {allParams}" - size = desc.DynamicNodeSize("input") - - category = "Utils" - documentation = """ - Colorize the pointcloud of a sfmData - """ - - inputs = [ - desc.File( - name="input", - label="SfMData", - description="Input SfMData file.", - value="", - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="output", - label="SfMData", - description="Path to the output SfM file.", - value="{nodeCacheFolder}/sfmData.abc", - ), - ] diff --git a/meshroom/nodes/aliceVision/SfMDistances.py b/meshroom/nodes/aliceVision/SfMDistances.py deleted file mode 100644 index 794a3a817b..0000000000 --- a/meshroom/nodes/aliceVision/SfMDistances.py +++ /dev/null @@ -1,63 +0,0 @@ -__version__ = "3.0" - -from meshroom.core import desc -from meshroom.core.utils import DESCRIBER_TYPES, VERBOSE_LEVEL - - -class SfMDistances(desc.AVCommandLineNode): - commandLine = 'aliceVision_sfmDistances {allParams}' - size = desc.DynamicNodeSize('input') - - documentation = ''' - ''' - - inputs = [ - desc.File( - name="input", - label="Input", - description="SfMData file.", - value="", - ), - desc.ChoiceParam( - name="objectType", - label="Type", - description="", - value="landmarks", - values=["landmarks", "cameras"], - ), - desc.ChoiceParam( - name="landmarksDescriberTypes", - label="Describer Types", - description="Describer types used to describe an image (only used when using 'landmarks').", - values=DESCRIBER_TYPES, - value=["cctag3"], - exclusive=False, - joinChar=",", - ), - desc.StringParam( - name="A", - label="A IDs", - description="It will display the distances between A and B elements.\n" - "This value should be an ID or a list of IDs of landmarks IDs or cameras (UID or filename without extension).\n" - "It will list all elements if empty.", - value="", - ), - desc.StringParam( - name="B", - label="B IDs", - description="It will display the distances between A and B elements.\n" - "This value should be an ID or a list of IDs of landmarks IDs or cameras (UID or filename without extension).\n" - "It will list all elements if empty.", - value="", - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - ] diff --git a/meshroom/nodes/aliceVision/SfMFilter.py b/meshroom/nodes/aliceVision/SfMFilter.py deleted file mode 100644 index 7193a65ec9..0000000000 --- a/meshroom/nodes/aliceVision/SfMFilter.py +++ /dev/null @@ -1,57 +0,0 @@ -__version__ = "1.0" - -from meshroom.core import desc -from meshroom.core.utils import VERBOSE_LEVEL - - -class SfMFilter(desc.CommandLineNode): - commandLine = 'aliceVision_sfmFilter {allParams}' - category = 'Utils' - documentation = ''' -This node allows select views from sfmData file using a regular expresion. -''' - - inputs = [ - desc.File( - name="inputFile", - label="inputFile", - description="SfMData file.", - value="", - ), - desc.StringParam( - name="fileMatchingPattern", - label="File Matching Pattern", - description="Matching regular expression.\n" - "You should capture specific parts of the filepath with parentheses to define matching elements.\n" - "Some examples of patterns:\n" - " - Match the filename without extension (default value): " - r'".*\/(.*?)\.\w{3}"' + "\n" - " - Match the filename suffix after \"_\": " - r'".*\/.*(_.*?\.\w{3})"' + "\n" - " - Match the filename prefix before \"_\": " - r'".*\/(.*?)_.*\.\w{3}"', - value=r'.*\/(.*?)\.\w{3}', - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="outputSfMData_selected", - label="SfMData_selected", - description="Output SfMData file containing selected views.", - value="{nodeCacheFolder}/selectedSfmData.sfm", - ), - desc.File( - name="outputSfMData_unselected", - label="SfMData_unselected", - description="Output SfMData file containing remaining views.", - value="{nodeCacheFolder}/unselectedSfmData.sfm", - ), - ] diff --git a/meshroom/nodes/aliceVision/SfMMerge.py b/meshroom/nodes/aliceVision/SfMMerge.py deleted file mode 100644 index eca1654e08..0000000000 --- a/meshroom/nodes/aliceVision/SfMMerge.py +++ /dev/null @@ -1,103 +0,0 @@ -__version__ = "3.0" - -from meshroom.core import desc -from meshroom.core.utils import DESCRIBER_TYPES, VERBOSE_LEVEL - -import os.path - -class MergeNodeSize(desc.DynamicNodeSize): - """ - MergeNodeSize expresses a dependency to multiple input attributess to define - the size of a Node in terms of individual tasks for parallelization. - """ - def __init__(self, param): - self._params = param - - def computeSize(self, node): - - size = 0 - - for input in node.attribute(self._params).value: - paramName = input.getFullName() - param = node.attribute(paramName) - size = size + param.getLinkParam().node.size - - return size - - -class SfMMerge(desc.AVCommandLineNode): - commandLine = 'aliceVision_sfmMerge {allParams}' - size = MergeNodeSize("inputs") - - category = 'Utils' - documentation = ''' -Merges two SfMData files into a single one. Fails if some UID is shared among them. -''' - - inputs = [ - desc.ListAttribute( - elementDesc=desc.File( - name="input", - label="Input SfmData", - description="A SfmData file.", - value="", - ), - name="inputs", - label="Inputs", - description="Set of SfmData (at least 1 is required).", - exposed=True, - ), - desc.ChoiceParam( - name="method", - label="Merge Method", - description="Merge method:\n" - " - simple copy: Straight copy without duplicate management.\n" - " - from_landmarks: Align from matched features, try to fuse.\n", - value="simple_copy", - values=["simple_copy", 'from_landmarks'], - ), - desc.ListAttribute( - elementDesc=desc.File( - name="matchesFolder", - label="Matches Folder", - description="", - value="", - ), - name="matchesFolders", - label="Matches Folders", - description="Folder(s) in which the computed matches are stored.", - ), - desc.ChoiceParam( - name="describerTypes", - label="Describer Types", - description="Describer types used to describe an image.", - values=DESCRIBER_TYPES, - value=["dspsift"], - exclusive=False, - joinChar=",", - ), - desc.ChoiceParam( - name="fileExt", - label="SfM File Format", - description="Output SfM file format.", - value="abc", - values=["abc", "sfm", "json"], - group="", # exclude from command line - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ) - ] - - outputs = [ - desc.File( - name="output", - label="SfMData", - description="Path to the output SfM file (in SfMData format).", - value="{nodeCacheFolder}/sfmData.{fileExtValue}", - ) - ] diff --git a/meshroom/nodes/aliceVision/SfMPoseInjecting.py b/meshroom/nodes/aliceVision/SfMPoseInjecting.py deleted file mode 100644 index f855235c04..0000000000 --- a/meshroom/nodes/aliceVision/SfMPoseInjecting.py +++ /dev/null @@ -1,55 +0,0 @@ -__version__ = "1.0" - -from meshroom.core import desc -from meshroom.core.utils import VERBOSE_LEVEL - -import json - -class SfMPoseInjecting(desc.AVCommandLineNode): - - commandLine = "aliceVision_sfmPoseInjecting {allParams}" - size = desc.DynamicNodeSize("input") - - category = "Utils" - documentation = """ -Use a JSON file to inject poses inside the SfMData. -""" - - inputs = [ - desc.File( - name="input", - label="SfMData", - description="Input SfMData file.", - value="", - ), - desc.File( - name="posesFilename", - label="Poses", - description="Input JSON file containing the poses.", - value="", - ), - desc.ChoiceParam( - name="rotationFormat", - label="Rotation Format", - description="Defines the rotation format for the input poses:\n" - " - EulerZXY: Euler rotation in degrees (Y*X*Z)", - values=["EulerZXY"], - value="EulerZXY", - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="output", - label="SfMData", - description="Path to the output SfM file.", - value="{nodeCacheFolder}/sfmData.abc", - ), - ] diff --git a/meshroom/nodes/aliceVision/SfMSplitReconstructed.py b/meshroom/nodes/aliceVision/SfMSplitReconstructed.py deleted file mode 100644 index eb237a416d..0000000000 --- a/meshroom/nodes/aliceVision/SfMSplitReconstructed.py +++ /dev/null @@ -1,47 +0,0 @@ -__version__ = "1.0" - -from meshroom.core import desc -from meshroom.core.utils import VERBOSE_LEVEL - - -class SfMSplitReconstructed(desc.AVCommandLineNode): - commandLine = 'aliceVision_sfmSplitReconstructed {allParams}' - size = desc.DynamicNodeSize('input') - - category = 'Utils' - documentation = ''' - This nodes takes a SfMData file as an input and splits it in two output SfMData files: - - One SfMData containing the reconstructed views - - One SfMData containing the non-reconstructed views -''' - - inputs = [ - desc.File( - name="input", - label="Input SfMData", - description="Input SfMData file.", - value="", - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="reconstructedOutput", - label="Reconstructed SfMData File", - description="SfMData file containing the reconstructed cameras.", - value="{nodeCacheFolder}/sfmReconstructed.abc", - ), - desc.File( - name="notReconstructedOutput", - label="Not Reconstructed SfMData File", - description="SfMData file containing the non-reconstructed cameras.", - value="{nodeCacheFolder}/sfmNonReconstructed.abc", - ), - ] diff --git a/meshroom/nodes/aliceVision/SfMSurveyInjecting.py b/meshroom/nodes/aliceVision/SfMSurveyInjecting.py deleted file mode 100644 index fc52ea574b..0000000000 --- a/meshroom/nodes/aliceVision/SfMSurveyInjecting.py +++ /dev/null @@ -1,47 +0,0 @@ -__version__ = "1.0" - -from meshroom.core import desc -from meshroom.core.utils import VERBOSE_LEVEL - -import json - -class SfMSurveyInjecting(desc.AVCommandLineNode): - - commandLine = "aliceVision_sfmSurveyInjecting {allParams}" - size = desc.DynamicNodeSize("input") - - category = "Utils" - documentation = """ -Use a JSON file to inject survey measurements inside the SfMData. -""" - - inputs = [ - desc.File( - name="input", - label="SfMData", - description="Input SfMData file.", - value="", - ), - desc.File( - name="surveyFilename", - label="Survey", - description="Input JSON file containing the survey.", - value="", - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="output", - label="SfMData", - description="Path to the output SfM file.", - value="{nodeCacheFolder}/sfmData.abc", - ), - ] diff --git a/meshroom/nodes/aliceVision/SfMToRig.py b/meshroom/nodes/aliceVision/SfMToRig.py deleted file mode 100644 index 468cf6c2ca..0000000000 --- a/meshroom/nodes/aliceVision/SfMToRig.py +++ /dev/null @@ -1,40 +0,0 @@ -__version__ = "1.0" - -from meshroom.core import desc -from meshroom.core.utils import VERBOSE_LEVEL - -import os.path - -class SfMToRig(desc.AVCommandLineNode): - commandLine = 'aliceVision_sfmToRig {allParams}' - size = desc.DynamicNodeSize('input') - - category = 'Utils' - documentation = ''' -Assumes the input SfMData describes a set of cameras capturing a scene at a common time. Transformd the set of cameras into a rig of cameras. -''' - - inputs = [ - desc.File( - name="input", - label="SfMData", - description="Input SfMData file.", - value="", - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="output", - label="SfMData", - description="Path to the output SfM file (in SfMData format).", - value="{nodeCacheFolder}/sfmData.sfm", - ), - ] diff --git a/meshroom/nodes/aliceVision/SfMTransfer.py b/meshroom/nodes/aliceVision/SfMTransfer.py deleted file mode 100644 index 2b144d4abc..0000000000 --- a/meshroom/nodes/aliceVision/SfMTransfer.py +++ /dev/null @@ -1,110 +0,0 @@ -__version__ = "2.1" - -from meshroom.core import desc -from meshroom.core.utils import VERBOSE_LEVEL - -import os.path - - -class SfMTransfer(desc.AVCommandLineNode): - commandLine = 'aliceVision_sfmTransfer {allParams}' - size = desc.DynamicNodeSize('input') - - category = 'Utils' - documentation = ''' -This node allows to transfer poses and/or intrinsics form one SfM scene onto another one. -''' - - inputs = [ - desc.File( - name="input", - label="Input", - description="SfMData file.", - value="", - ), - desc.File( - name="reference", - label="Reference", - description="Path to the scene used as the reference to retrieve resolved poses and intrinsics.", - value="", - ), - desc.ChoiceParam( - name="method", - label="Matching Method", - description="Matching Method:\n" - " - from_viewid: Match cameras based on viewId.\n" - " - from_filepath: Match cameras with a filepath matching, using 'fileMatchingPattern'.\n" - " - from_metadata: Match cameras with matching metadata, using 'metadataMatchingList'.\n" - " - from_poseid: Match cameras based on poseId.\n" - " - from_intrinsicid: Match cameras based on intrinsicId.\n", - value="from_viewid", - values=["from_viewid", "from_filepath", "from_metadata", "from_poseid", "from_intrinsicid"], - ), - desc.StringParam( - name="fileMatchingPattern", - label="File Matching Pattern", - description="Matching regular expression for the 'from_cameras_filepath' method.\n" - "You should capture specific parts of the filepath with parentheses to define matching elements.\n" - "Some examples of patterns:\n" - " - Match the filename without extension (default value): " - r'".*\/(.*?)\.\w{3}"' + "\n" - " - Match the filename suffix after \"_\": " - r'".*\/.*(_.*?\.\w{3})"' + "\n" - " - Match the filename prefix before \"_\": " - r'".*\/(.*?)_.*\.\w{3}"', - value=r'.*\/(.*?)\.\w{3}', - ), - desc.ListAttribute( - elementDesc=desc.File( - name="metadataMatching", - label="Metadata", - description="Metadata that should match to create correspondences.", - value="", - ), - name="metadataMatchingList", - label="Metadata Matching List", - description="List of metadata that should match to create the correspondences.\n" - "If the list is empty, the default value will be used:\n" - "['Make', 'Model', 'Exif:BodySerialNumber', 'Exif:LensSerialNumber'].", - ), - desc.BoolParam( - name="transferPoses", - label="Poses", - description="Transfer poses.", - value=True, - ), - desc.BoolParam( - name="transferIntrinsics", - label="Intrinsics", - description="Transfer cameras intrinsics.", - value=True, - ), - desc.BoolParam( - name="transferLandmarks", - label="Landmarks", - description="Transfer landmarks.", - value=True, - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="output", - label="SfMData", - description="Path to the output SfM point cloud file (in SfMData format).", - value=lambda attr: "{nodeCacheFolder}/" + (os.path.splitext(os.path.basename(attr.node.input.value))[0] or "sfmData") + ".abc", - ), - desc.File( - name="outputViewsAndPoses", - label="Poses", - description="Path to the output SfMData file with cameras (views and poses).", - value="{nodeCacheFolder}/cameras.sfm", - ), - ] diff --git a/meshroom/nodes/aliceVision/SfMTransform.py b/meshroom/nodes/aliceVision/SfMTransform.py deleted file mode 100644 index eab001937b..0000000000 --- a/meshroom/nodes/aliceVision/SfMTransform.py +++ /dev/null @@ -1,266 +0,0 @@ -__version__ = "3.1" - -from meshroom.core import desc -from meshroom.core.utils import DESCRIBER_TYPES, VERBOSE_LEVEL - -import os.path - - -class SfMTransform(desc.AVCommandLineNode): - commandLine = 'aliceVision_sfmTransform {allParams}' - size = desc.DynamicNodeSize('input') - - category = 'Utils' - documentation = ''' -This node allows to change the coordinate system of one SfM scene. - -The transformation can be based on: - * transformation: Apply a given transformation - * auto_from_cameras: Fit all cameras into a box [-1,1] - * auto_from_landmarks: Fit all landmarks into a box [-1,1] - * from_single_camera: Use a specific camera as the origin of the coordinate system - * from_markers: Align specific markers to custom coordinates - * from_gps: Align with the gps positions from the image metadata - * align_ground: Detect ground level and align to it - * from_lineup: Align using a camera pose (json line up file), tracks and a mesh -''' - - inputs = [ - desc.File( - name="input", - label="Input", - description="SfMData file.", - value="", - ), - desc.ChoiceParam( - name="method", - label="Transformation Method", - description="Transformation method:\n" - " - transformation: Apply a given transformation.\n" - " - manual: Apply the gizmo transformation (show the transformed input).\n" - " - auto: Determines scene orientation from the cameras' X axis, determines north and scale from GPS information if available, and defines ground level from the point cloud.\n" - " - auto_from_cameras: Defines coordinate system from cameras.\n" - " - auto_from_cameras_x_axis: Determines scene orientation from the cameras' X axis.\n" - " - auto_from_landmarks: Defines coordinate system from landmarks.\n" - " - from_single_camera: Defines the coordinate system from the camera specified by --tranformation.\n" - " - from_center_camera: Defines the coordinate system from the camera closest to the center of the reconstruction.\n" - " - from_markers: Defines the coordinate system from markers specified by --markers.\n" - " - from_gps: Defines coordinate system from GPS metadata.\n" - " - from_lineup: Defines coordinate system using lineup json file.\n" - " - align_ground: Defines ground level from the point cloud density. It assumes that the scene is oriented.", - value="auto", - values=["transformation", "manual", "auto", "auto_from_cameras", "auto_from_cameras_x_axis", "auto_from_landmarks", "from_single_camera", "from_center_camera", "from_markers", "from_gps", "from_lineup", "align_ground"], - ), - desc.File( - name="lineUp", - label="Line Up File", - description="LineUp Json file.", - value="", - enabled=lambda node: node.method.value == "from_lineup" - ), - desc.File( - name="tracksFile", - label="Tracks File", - description="Tracks file for lineup.", - value="", - enabled=lambda node: node.method.value == "from_lineup" - ), - desc.File( - name="objectFile", - label="Mesh File", - description="Mesh file for lineup.", - value="", - enabled=lambda node: node.method.value == "from_lineup" - ), - desc.StringParam( - name="transformation", - label="Transformation", - description="Required only for 'transformation' and 'from_single_camera' methods:\n" - " - transformation: Align [X,Y,Z] to +Y-axis, rotate around Y by R deg, scale by S; syntax: X,Y,Z;R;S\n" - " - from_single_camera: Camera UID or simplified regular expression to match image filepath (like '*camera2*.jpg').", - value="", - enabled=lambda node: node.method.value == "transformation" or node.method.value == "from_single_camera" or node.method.value == "auto_from_cameras_x_axis", - ), - desc.GroupAttribute( - name="manualTransform", - label="Manual Transform (Gizmo)", - description="Translation, rotation (Euler ZXY) and uniform scale.", - groupDesc=[ - desc.GroupAttribute( - name="manualTranslation", - label="Translation", - description="Translation in space.", - groupDesc=[ - desc.FloatParam( - name="x", - label="x", - description="X offset.", - value=0.0, - range=(-20.0, 20.0, 0.01), - ), - desc.FloatParam( - name="y", - label="y", - description="Y offset.", - value=0.0, - range=(-20.0, 20.0, 0.01), - ), - desc.FloatParam( - name="z", - label="z", - description="Z offset.", - value=0.0, - range=(-20.0, 20.0, 0.01), - ), - ], - joinChar=",", - ), - desc.GroupAttribute( - name="manualRotation", - label="Euler Rotation", - description="Rotation in Euler angles.", - groupDesc=[ - desc.FloatParam( - name="x", - label="x", - description="Euler X rotation.", - value=0.0, - range=(-90.0, 90.0, 1.0), - ), - desc.FloatParam( - name="y", - label="y", - description="Euler Y rotation.", - value=0.0, - range=(-180.0, 180.0, 1.0), - ), - desc.FloatParam( - name="z", - label="z", - description="Euler Z rotation.", - value=0.0, - range=(-180.0, 180.0, 1.0), - ), - ], - joinChar=",", - ), - desc.FloatParam( - name="manualScale", - label="Scale", - description="Uniform scale.", - value=1.0, - range=(0.0, 20.0, 0.01), - ), - ], - joinChar=",", - enabled=lambda node: node.method.value == "manual", - ), - desc.ChoiceParam( - name="landmarksDescriberTypes", - label="Landmarks Describer Types", - description="Image describer types used to compute the mean of the point cloud (only for 'landmarks' method).", - values=DESCRIBER_TYPES, - value=["sift", "dspsift", "akaze"], - exclusive=False, - joinChar=",", - ), - desc.FloatParam( - name="scale", - label="Additional Scale", - description="Additional scale to apply.", - value=1.0, - range=(0.0, 100.0, 0.1), - ), - desc.ListAttribute( - name="markers", - elementDesc=desc.GroupAttribute( - name="markerAlign", - label="Marker Align", - description="", - joinChar=":", - groupDesc=[ - desc.IntParam( - name="markerId", - label="Marker", - description="Marker ID.", - value=0, - range=(0, 32, 1), - ), - desc.GroupAttribute( - name="markerCoord", - label="Coord", - description="Marker coordinates.", - joinChar=",", - groupDesc=[ - desc.FloatParam( - name="x", - label="x", - description="X coordinates for the marker.", - value=0.0, - range=(-2.0, 2.0, 1.0), - ), - desc.FloatParam( - name="y", - label="y", - description="Y coordinates for the marker.", - value=0.0, - range=(-2.0, 2.0, 1.0), - ), - desc.FloatParam( - name="z", - label="z", - description="Z coordinates for the marker.", - value=0.0, - range=(-2.0, 2.0, 1.0), - ), - ], - ), - ], - ), - label="Markers", - description="Markers alignment points.", - ), - desc.BoolParam( - name="applyScale", - label="Scale", - description="Apply scale transformation.", - value=True, - enabled=lambda node: node.method.value != "manual", - ), - desc.BoolParam( - name="applyRotation", - label="Rotation", - description="Apply rotation transformation.", - value=True, - enabled=lambda node: node.method.value != "manual", - ), - desc.BoolParam( - name="applyTranslation", - label="Translation", - description="Apply translation transformation.", - value=True, - enabled=lambda node: node.method.value != "manual", - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="output", - label="SfMData File", - description="Aligned SfMData file.", - value=lambda attr: "{nodeCacheFolder}/" + (os.path.splitext(os.path.basename(attr.node.input.value))[0] or "sfmData") + ".abc", - ), - desc.File( - name="outputViewsAndPoses", - label="Poses", - description="Path to the output SfMData file with cameras (views and poses).", - value="{nodeCacheFolder}/cameras.sfm", - ), - ] diff --git a/meshroom/nodes/aliceVision/SfMTriangulation.py b/meshroom/nodes/aliceVision/SfMTriangulation.py deleted file mode 100644 index 06ce61ed00..0000000000 --- a/meshroom/nodes/aliceVision/SfMTriangulation.py +++ /dev/null @@ -1,154 +0,0 @@ -__version__ = "1.0" - -from meshroom.core import desc -from meshroom.core.utils import DESCRIBER_TYPES, VERBOSE_LEVEL - - -class SfMTriangulation(desc.AVCommandLineNode): - commandLine = 'aliceVision_sfmTriangulation {allParams}' - size = desc.DynamicNodeSize('input') - - category = 'Sparse Reconstruction' - documentation = ''' -This node perfoms keypoint triangulation on its input data. -Contrary to the StructureFromMotion node, this node does not infer the camera poses, therefore they must be given in the SfMData input. -''' - - inputs = [ - desc.File( - name="input", - label="SfMData", - description="SfMData file. Must contain the camera calibration.", - value="", - ), - desc.ListAttribute( - elementDesc=desc.File( - name="featuresFolder", - label="Features Folder", - description="Folder containing some extracted features and descriptors.", - value="", - ), - name="featuresFolders", - label="Features Folders", - description="Folder(s) containing the extracted features and descriptors.", - exposed=True, - ), - desc.ListAttribute( - elementDesc=desc.File( - name="matchesFolder", - label="Matches Folder", - description="Folder in which some computed matches are stored.", - value="", - ), - name="matchesFolders", - label="Matches Folders", - description="Folder(s) in which computed matches are stored.", - exposed=True, - ), - desc.ChoiceParam( - name="describerTypes", - label="Describer Types", - description="Describer types used to describe an image.", - values=DESCRIBER_TYPES, - value=["dspsift"], - exclusive=False, - joinChar=",", - ), - desc.IntParam( - name="maxNumberOfMatches", - label="Maximum Number Of Matches", - description="Maximum number of matches per image pair (and per feature type).\n" - "This can be useful to have a quick reconstruction overview.\n" - "0 means no limit.", - value=0, - range=(0, 50000, 1), - ), - desc.IntParam( - name="minNumberOfMatches", - label="Minimum Number Of Matches", - description="Minimum number of matches per image pair (and per feature type).\n" - "This can be useful to have a meaningful reconstruction with accurate keypoints.\n" - "0 means no limit.", - value=0, - range=(0, 50000, 1), - ), - desc.IntParam( - name="minNumberOfObservationsForTriangulation", - label="Min Observations For Triangulation", - description="Minimum number of observations to triangulate a point.\n" - "Setting it to 3 (or more) reduces drastically the noise in the point cloud,\n" - "but the number of final poses is a little bit reduced\n" - "(from 1.5% to 11% on the tested datasets).", - value=2, - range=(2, 10, 1), - advanced=True, - ), - desc.FloatParam( - name="minAngleForTriangulation", - label="Min Angle For Triangulation", - description="Minimum angle for triangulation.", - value=3.0, - range=(0.1, 10.0, 0.1), - advanced=True, - ), - desc.FloatParam( - name="minAngleForLandmark", - label="Min Angle For Landmark", - description="Minimum angle for landmark.", - value=2.0, - range=(0.1, 10.0, 0.1), - advanced=True, - ), - desc.BoolParam( - name="useRigConstraint", - label="Use Rig Constraint", - description="Enable/Disable rig constraint.", - value=True, - advanced=True, - ), - desc.IntParam( - name="rigMinNbCamerasForCalibration", - label="Min Nb Cameras For Rig Calibration", - description="Minimum number of cameras to start the calibration of the rig.", - value=20, - range=(1, 50, 1), - advanced=True, - ), - desc.BoolParam( - name="computeStructureColor", - label="Compute Structure Color", - description="Enable/Disable color computation of each 3D point.", - value=True, - ), - desc.ChoiceParam( - name="interFileExtension", - label="Inter File Extension", - description="Extension of the intermediate file export.", - value=".abc", - values=[".abc", ".ply"], - invalidate=False, - advanced=True, - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="output", - label="SfMData", - description="Path to the output SfMData file.", - value="{nodeCacheFolder}/sfm.abc", - ), - desc.File( - name="extraInfoFolder", - label="Folder", - description="Folder for intermediate reconstruction files and additional reconstruction information files.", - value="{nodeCacheFolder}", - ), - ] diff --git a/meshroom/nodes/aliceVision/SfmBootstraping.py b/meshroom/nodes/aliceVision/SfmBootstraping.py deleted file mode 100644 index d4b293914b..0000000000 --- a/meshroom/nodes/aliceVision/SfmBootstraping.py +++ /dev/null @@ -1,84 +0,0 @@ -__version__ = "3.0" - -from meshroom.core import desc -from meshroom.core.utils import VERBOSE_LEVEL - - -class SfMBootStraping(desc.AVCommandLineNode): - commandLine = 'aliceVision_sfmBootstraping {allParams}' - size = desc.DynamicNodeSize('input') - - category = 'Sparse Reconstruction' - documentation = ''' -''' - - inputs = [ - desc.File( - name="input", - label="SfMData", - description="SfMData file.", - value="", - ), - desc.File( - name="tracksFilename", - label="Tracks File", - description="Tracks file.", - value="", - ), - desc.File( - name="meshFilename", - label="Mesh File", - description="Mesh file (*.obj).", - value="", - ), - desc.File( - name="pairs", - label="Pairs File", - description="Information on pairs.", - value="", - ), - desc.FloatParam( - name="minAngleInitialPair", - label="Min Angle Initial Pair", - description="Minimum angle for the initial pair.", - value=5.0, - range=(0.1, 10.0, 0.1), - advanced=True, - ), - desc.FloatParam( - name="maxAngleInitialPair", - label="Max Angle Initial Pair", - description="Maximum angle for the initial pair.", - value=40.0, - range=(0.1, 60.0, 0.1), - advanced=True, - ), - desc.File( - name="initialPairA", - label="Initial Pair A", - description="View ID of the first image.", - value="", - ), - desc.File( - name="initialPairB", - label="Initial Pair B", - description="View ID of the second image.", - value="", - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="output", - label="SfMData", - description="Path to the output SfMData file.", - value="{nodeCacheFolder}/bootstrap.abc", - ), - ] diff --git a/meshroom/nodes/aliceVision/SfmExpanding.py b/meshroom/nodes/aliceVision/SfmExpanding.py deleted file mode 100644 index 4328dbafa8..0000000000 --- a/meshroom/nodes/aliceVision/SfmExpanding.py +++ /dev/null @@ -1,181 +0,0 @@ -__version__ = "2.0" - -from meshroom.core import desc -from meshroom.core.utils import VERBOSE_LEVEL - - -class SfMExpanding(desc.AVCommandLineNode): - commandLine = 'aliceVision_sfmExpanding {allParams}' - size = desc.DynamicNodeSize('input') - - cpu = desc.Level.INTENSIVE - ram = desc.Level.INTENSIVE - - category = 'Sparse Reconstruction' - documentation = ''' -''' - - inputs = [ - desc.File( - name="input", - label="SfMData", - description="SfMData file.", - value="", - ), - desc.File( - name="tracksFilename", - label="Tracks File", - description="Tracks file.", - value="", - ), - desc.File( - name="meshFilename", - label="Mesh File", - description="Mesh file (*.obj).", - value="", - ), - desc.IntParam( - name="localizerEstimatorMaxIterations", - label="Localizer Max Ransac Iterations", - description="Maximum number of iterations allowed in the Ransac step.", - value=50000, - range=(1, 100000, 1), - advanced=True, - ), - desc.FloatParam( - name="localizerEstimatorError", - label="Localizer Max Ransac Error", - description="Maximum error (in pixels) allowed for camera localization (resectioning).\n" - "If set to 0, it will select a threshold according to the localizer estimator used\n" - "(if ACRansac, it will analyze the input data to select the optimal value).", - value=0.0, - range=(0.0, 100.0, 0.1), - advanced=True, - ), - desc.BoolParam( - name="lockScenePreviouslyReconstructed", - label="Lock Previously Reconstructed Scene", - description="Lock previously reconstructed poses and intrinsics.\n" - "This option is useful for SfM augmentation.", - value=False, - ), - desc.BoolParam( - name="useLocalBA", - label="Local Bundle Adjustment", - description="It reduces the reconstruction time, especially for large datasets (500+ images),\n" - "by avoiding computation of the Bundle Adjustment on areas that are not changing.", - value=True, - ), - desc.IntParam( - name="localBAGraphDistance", - label="LocalBA Graph Distance", - description="Graph-distance limit to define the active region in the Local Bundle Adjustment strategy.", - value=1, - range=(2, 10, 1), - advanced=True, - ), - desc.IntParam( - name="nbFirstUnstableCameras", - label="First Unstable Cameras Nb", - description="Number of cameras for which the bundle adjustment is performed every single time a camera is added.\n" - "This leads to more stable results while computations are not too expensive, as there is little data.\n" - "Past this number, the bundle adjustment will only be performed once for N added cameras.", - value=30, - range=(0, 100, 1), - advanced=True, - ), - desc.IntParam( - name="maxImagesPerGroup", - label="Max Images Per Group", - description="Maximum number of cameras that can be added before the bundle adjustment has to be performed again.\n" - "This prevents adding too much data at once without performing the bundle adjustment.", - value=30, - range=(0, 100, 1), - advanced=True, - ), - desc.IntParam( - name="bundleAdjustmentMaxOutliers", - label="Max Nb Of Outliers After BA", - description="Threshold for the maximum number of outliers allowed at the end of a bundle adjustment iteration.\n" - "Using a negative value for this threshold will disable BA iterations.", - value=50, - range=(-1, 1000, 1), - advanced=True, - ), - desc.IntParam( - name="minNumberOfObservationsForTriangulation", - label="Min Observations For Triangulation", - description="Minimum number of observations to triangulate a point.\n" - "Setting it to 3 (or more) reduces drastically the noise in the point cloud,\n" - "but the number of final poses is a little bit reduced\n" - "(from 1.5% to 11% on the tested datasets).", - value=2, - range=(2, 10, 1), - advanced=True, - ), - desc.FloatParam( - name="minAngleForTriangulation", - label="Min Angle For Triangulation", - description="Minimum angle for triangulation.", - value=3.0, - range=(0.1, 10.0, 0.1), - advanced=True, - ), - desc.FloatParam( - name="minAngleForLandmark", - label="Min Angle For Landmark", - description="Minimum angle for landmark.", - value=2.0, - range=(0.1, 10.0, 0.1), - advanced=True, - ), - desc.FloatParam( - name="maxReprojectionError", - label="Max Reprojection Error", - description="Maximum reprojection error.", - value=4.0, - range=(0.1, 10.0, 0.1), - advanced=True, - ), - desc.BoolParam( - name="lockAllIntrinsics", - label="Lock All Intrinsic Camera Parameters", - description="Force to keep all the intrinsic parameters of the cameras (focal length, \n" - "principal point, distortion if any) constant during the reconstruction.\n" - "This may be helpful if the input cameras are already fully calibrated.", - value=False, - ), - desc.IntParam( - name="minNbCamerasToRefinePrincipalPoint", - label="Min Nb Cameras To Refine Principal Point", - description="Minimum number of cameras to refine the principal point of the cameras (one of the intrinsic parameters of the camera).\n" - "If we do not have enough cameras, the principal point is considered to be in the center of the image.\n" - "If minNbCamerasToRefinePrincipalPoint <= 0, the principal point is never refined." - "If minNbCamerasToRefinePrincipalPoint is set to 1, the principal point is always refined.", - value=3, - range=(0, 20, 1), - advanced=True, - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="output", - label="SfMData", - description="Path to the output SfMData file.", - value="{nodeCacheFolder}/sfmExpanded.abc", - ), - desc.File( - name="outputViewsAndPoses", - label="Views And Poses", - description="Path to the output SfMData file with cameras (views and poses).", - value="{nodeCacheFolder}/cameras.sfm", - ) - ] diff --git a/meshroom/nodes/aliceVision/SketchfabUpload.py b/meshroom/nodes/aliceVision/SketchfabUpload.py deleted file mode 100644 index cb940b85c6..0000000000 --- a/meshroom/nodes/aliceVision/SketchfabUpload.py +++ /dev/null @@ -1,275 +0,0 @@ -__version__ = "1.0" - -from meshroom.core import desc -from meshroom.core.utils import VERBOSE_LEVEL - -import glob -import os -import json -import zipfile -import requests -import io - - -class BufferReader(io.BytesIO): # object to call the callback while the file is being uploaded - def __init__(self, buf=b'', - callback=None, - cb_args=(), - cb_kwargs={}, - stopped=None): - self._callback = callback - self._cb_args = cb_args - self._cb_kwargs = cb_kwargs - self._stopped = stopped - self._progress = 0 - self._len = len(buf) - io.BytesIO.__init__(self, buf) - - def __len__(self): - return self._len - - def read(self, n=-1): - chunk = io.BytesIO.read(self, n) - self._progress += int(len(chunk)) - self._cb_kwargs.update({ - 'size' : self._len, - 'progress': self._progress - }) - if self._callback: - try: - self._callback(*self._cb_args, **self._cb_kwargs) - except Exception as e: # catches exception from the callback - self._cb_kwargs['logManager'].logger.warning('Error at callback: {}'.format(e)) - - if self._stopped(): - raise RuntimeError('Node stopped by user') - return chunk - -def progressUpdate(size=None, progress=None, logManager=None): - if not logManager.progressBar: - logManager.makeProgressBar(size, 'Upload progress:') - - logManager.updateProgressBar(progress) - -class SketchfabUpload(desc.Node): - size = desc.DynamicNodeSize('inputFiles') - - category = 'Export' - documentation = ''' -Upload a textured mesh on Sketchfab. -''' - - inputs = [ - desc.ListAttribute( - elementDesc=desc.File( - name="input", - label="Input", - description="", - value="", - ), - name="inputFiles", - label="Input Files", - description="Input Files to export.", - group="", - ), - desc.StringParam( - name="apiToken", - label="API Token", - description="Get your token from https://sketchfab.com/settings/password.", - value="", - ), - desc.StringParam( - name="title", - label="Title", - description="Title cannot be longer than 48 characters.", - value="", - ), - desc.StringParam( - name="description", - label="Description", - description="Description cannot be longer than 1024 characters.", - value="", - ), - desc.ChoiceParam( - name="license", - label="License", - description="License label.", - value="CC Attribution", - values=["CC Attribution", - "CC Attribution-ShareAlike", - "CC Attribution-NoDerivs", - "CC Attribution-NonCommercial", - "CC Attribution-NonCommercial-ShareAlike", - "CC Attribution-NonCommercial-NoDerivs"], - ), - desc.ListAttribute( - elementDesc=desc.StringParam( - name="tag", - label="Tag", - description="Tag cannot be longer than 48 characters.", - value="", - ), - name="tags", - label="Tags", - description="Maximum of 42 separate tags.", - group="", - ), - desc.ChoiceParam( - name="category", - label="Category", - description="Adding categories helps improve the discoverability of your model.", - value="none", - values=["none", - "animals-pets", - "architecture", - "art-abstract", - "cars-vehicles", - "characters-creatures", - "cultural-heritage-history", - "electronics-gadgets", - "fashion-style", - "food-drink", - "furniture-home", - "music", - "nature-plants", - "news-politics", - "people", - "places-travel", - "science-technology", - "sports-fitness", - "weapons-military"], - ), - desc.BoolParam( - name="isPublished", - label="Publish", - description="If the model is not published, it will be saved as a draft.", - value=False, - ), - desc.BoolParam( - name="isInspectable", - label="Inspectable", - description="Allow 2D view in model inspector.", - value=True, - ), - desc.BoolParam( - name="isPrivate", - label="Private", - description="Requires a pro account.", - value=False, - ), - desc.StringParam( - name="password", - label="Password", - description="Requires a pro account.", - value="", - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - def upload(self, apiToken, modelFile, data, chunk): - modelEndpoint = 'https://api.sketchfab.com/v3/models' - f = open(modelFile, 'rb') - file = {'modelFile': (os.path.basename(modelFile), f.read())} - file.update(data) - f.close() - (files, contentType) = requests.packages.urllib3.filepost.encode_multipart_formdata(file) - headers = {'Authorization': 'Token {}'.format(apiToken), 'Content-Type': contentType} - body = BufferReader(files, progressUpdate, cb_kwargs={'logManager': chunk.logManager}, stopped=self.stopped) - chunk.logger.info('Uploading...') - try: - r = requests.post( - modelEndpoint, **{'data': body, 'headers': headers}) - chunk.logManager.completeProgressBar() - except requests.exceptions.RequestException as e: - chunk.logger.error(u'An error occurred: {}'.format(e)) - raise RuntimeError() - if r.status_code != requests.codes.created: - chunk.logger.error(u'Upload failed with error: {}'.format(r.json())) - raise RuntimeError() - - def resolvedPaths(self, inputFiles): - paths = [] - for inputFile in inputFiles: - if os.path.isdir(inputFile.value): - for path, subdirs, files in os.walk(inputFile.value): - for name in files: - paths.append(os.path.join(path, name)) - else: - for f in glob.glob(inputFile.value): - paths.append(f) - return paths - - def stopped(self): - return self._stopped - - def processChunk(self, chunk): - try: - self._stopped = False - chunk.logManager.start(chunk.node.verboseLevel.value) - uploadFile = '' - - if not chunk.node.inputFiles: - chunk.logger.warning('Nothing to upload') - return - if chunk.node.apiToken.value == '': - chunk.logger.error('Need API token.') - raise RuntimeError() - if len(chunk.node.title.value) > 48: - chunk.logger.error('Title cannot be longer than 48 characters.') - raise RuntimeError() - if len(chunk.node.description.value) > 1024: - chunk.logger.error('Description cannot be longer than 1024 characters.') - raise RuntimeError() - tags = [ i.value.replace(' ', '-') for i in chunk.node.tags.value.values() ] - if all(len(i) > 48 for i in tags) and len(tags) > 0: - chunk.logger.error('Tags cannot be longer than 48 characters.') - raise RuntimeError() - if len(tags) > 42: - chunk.logger.error('Maximum of 42 separate tags.') - raise RuntimeError() - - data = { - 'name': chunk.node.title.value, - 'description': chunk.node.description.value, - 'license': chunk.node.license.value, - 'tags': str(tags), - 'isPublished': chunk.node.isPublished.value, - 'isInspectable': chunk.node.isInspectable.value, - 'private': chunk.node.isPrivate.value, - 'password': chunk.node.password.value - } - if chunk.node.category.value != 'none': - data.update({'categories': chunk.node.category.value}) - chunk.logger.debug('Data to be sent: {}'.format(str(data))) - - # pack files into .zip to reduce file size and simplify process - uploadFile = os.path.join(chunk.node.internalFolder, 'temp.zip') - files = self.resolvedPaths(chunk.node.inputFiles.value) - zf = zipfile.ZipFile(uploadFile, 'w') - for file in files: - zf.write(file, os.path.basename(file)) - zf.close() - chunk.logger.debug('Files added to zip: {}'.format(str(files))) - chunk.logger.debug('Created {}'.format(uploadFile)) - chunk.logger.info('File size: {}MB'.format(round(os.path.getsize(uploadFile)/(1024*1024), 3))) - - self.upload(chunk.node.apiToken.value, uploadFile, data, chunk) - chunk.logger.info('Upload successful. Your model is being processed on Sketchfab. It may take some time to show up on your "models" page.') - except Exception as e: - chunk.logger.error(e) - raise RuntimeError() - finally: - if os.path.isfile(uploadFile): - os.remove(uploadFile) - chunk.logger.debug('Deleted {}'.format(uploadFile)) - - chunk.logManager.end() - - def stopProcess(self, chunk): - self._stopped = True diff --git a/meshroom/nodes/aliceVision/SphereDetection.py b/meshroom/nodes/aliceVision/SphereDetection.py deleted file mode 100644 index a58fcba98c..0000000000 --- a/meshroom/nodes/aliceVision/SphereDetection.py +++ /dev/null @@ -1,89 +0,0 @@ -__version__ = "1.0" - -from meshroom.core import desc -from meshroom.core.utils import VERBOSE_LEVEL - - -class SphereDetection(desc.CommandLineNode): - commandLine = 'aliceVision_sphereDetection {allParams}' - category = 'Photometric Stereo' - documentation = ''' -Detect spheres in pictures. These spheres will be used for lighting calibration. -Spheres can be automatically detected or manually defined in the interface. -''' - - inputs = [ - desc.File( - name="input", - label="SfMData", - description="Input SfMData file.", - value="", - ), - desc.File( - name="modelPath", - label="Detection Network", - description="Deep learning network for automatic calibration sphere detection.", - value="${ALICEVISION_SPHERE_DETECTION_MODEL}", - ), - desc.BoolParam( - name="autoDetect", - label="Automatic Sphere Detection", - description="Automatic detection of calibration spheres.", - value=False, - ), - desc.FloatParam( - name="minScore", - label="Minimum Score", - description="Minimum score for the detection.", - value=0.0, - range=(0.0, 50.0, 0.01), - advanced=True, - ), - desc.GroupAttribute( - name="sphereCenter", - label="Sphere Center", - description="Center of the circle (XY offset to the center of the image in pixels).", - groupDesc=[ - desc.FloatParam( - name="x", - label="x", - description="X offset in pixels.", - value=0.0, - range=(-1000.0, 10000.0, 1.0), - ), - desc.FloatParam( - name="y", - label="y", - description="Y offset in pixels.", - value=0.0, - range=(-1000.0, 10000.0, 1.0), - ), - ], - enabled=lambda node: not node.autoDetect.value, - group=None, # skip group from command line - ), - desc.FloatParam( - name="sphereRadius", - label="Radius", - description="Sphere radius in pixels.", - value=500.0, - range=(0.0, 10000.0, 0.1), - enabled=lambda node: not node.autoDetect.value, - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="output", - label="Output Path", - description="Sphere detection information will be written here.", - value="{nodeCacheFolder}/detection.json", - ) - ] diff --git a/meshroom/nodes/aliceVision/Split360Images.py b/meshroom/nodes/aliceVision/Split360Images.py deleted file mode 100644 index b14db371c9..0000000000 --- a/meshroom/nodes/aliceVision/Split360Images.py +++ /dev/null @@ -1,139 +0,0 @@ -__version__ = "3.0" - -from meshroom.core import desc -from meshroom.core.utils import VERBOSE_LEVEL - - -class Split360InputNodeSize(desc.DynamicNodeSize): - ''' - The Split360Images will increase the amount of views in the SfMData. - This class converts the number of input views into the number of split output views. - ''' - def computeSize(self, node): - s = super(Split360InputNodeSize, self).computeSize(node) - factor = 0 - mode = node.attribute('splitMode') - if mode.value == 'equirectangular': - factor = node.attribute('equirectangularGroup.equirectangularNbSplits').value - elif mode.value == 'dualfisheye': - factor = 2 - return s * factor - - -class Split360Images(desc.AVCommandLineNode): - commandLine = 'aliceVision_split360Images {allParams}' - size = Split360InputNodeSize('input') - - category = 'Utils' - documentation = "This node is used to extract multiple images from equirectangular or dualfisheye images." - - inputs = [ - desc.File( - name="input", - label="Input", - description="Single image, image folder or SfMData file.", - value="", - ), - desc.ChoiceParam( - name="splitMode", - label="Split Mode", - description="Split mode (equirectangular, dualfisheye).", - value="equirectangular", - values=["equirectangular", "dualfisheye"], - ), - desc.GroupAttribute( - name="dualFisheyeGroup", - label="Dual Fisheye", - description="Dual Fisheye.", - group=None, - enabled=lambda node: node.splitMode.value == "dualfisheye", - groupDesc=[ - desc.ChoiceParam( - name="dualFisheyeOffsetPresetX", - label="X Offset Preset", - description="Dual-Fisheye X offset preset.", - value="center", - values=["center", "left", "right"], - ), - desc.ChoiceParam( - name="dualFisheyeOffsetPresetY", - label="Y Offset Preset", - description="Dual-Fisheye Y offset preset.", - value="center", - values=["center", "top", "bottom"], - ), - desc.ChoiceParam( - name="dualFisheyeCameraModel", - label="Camera Model", - description="Dual-Fisheye camera model.", - value="fisheye4", - values=["fisheye4", "equidistant_r3"], - ), - ], - ), - desc.GroupAttribute( - name="equirectangularGroup", - label="Equirectangular", - description="Equirectangular", - group=None, - enabled=lambda node: node.splitMode.value == "equirectangular", - groupDesc=[ - desc.IntParam( - name="equirectangularNbSplits", - label="Nb Splits", - description="Equirectangular number of splits.", - value=2, - range=(1, 100, 1), - ), - desc.IntParam( - name="equirectangularSplitResolution", - label="Split Resolution", - description="Equirectangular split resolution.", - value=1200, - range=(100, 10000, 1), - ), - desc.BoolParam( - name="equirectangularPreviewMode", - label="Preview Mode", - description="Export a SVG file that simulates the split.", - value=False, - ), - desc.FloatParam( - name="fov", - label="Field Of View", - description="Field of View to extract (in degrees).", - value=110.0, - range=(0.0, 180.0, 1.0), - ), - ], - ), - desc.ChoiceParam( - name="extension", - label="Output File Extension", - description="Output image file extension.", - value="", - values=["", "exr", "jpg", "tiff", "png"], - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="output", - label="Folder", - description="Output folder for extracted frames.", - value="{nodeCacheFolder}", - ), - desc.File( - name="outSfMData", - label="SfMData File", - description="Output SfMData file.", - value="{nodeCacheFolder}/rig.sfm", - ), - ] diff --git a/meshroom/nodes/aliceVision/StructureFromMotion.py b/meshroom/nodes/aliceVision/StructureFromMotion.py deleted file mode 100644 index 393d3143db..0000000000 --- a/meshroom/nodes/aliceVision/StructureFromMotion.py +++ /dev/null @@ -1,393 +0,0 @@ -__version__ = "3.3" - -from meshroom.core import desc -from meshroom.core.utils import DESCRIBER_TYPES, VERBOSE_LEVEL - - -class StructureFromMotion(desc.AVCommandLineNode): - commandLine = 'aliceVision_incrementalSfM {allParams}' - size = desc.DynamicNodeSize('input') - - cpu = desc.Level.INTENSIVE - ram = desc.Level.INTENSIVE - - category = 'Sparse Reconstruction' - documentation = ''' -This node will analyze feature matches to understand the geometric relationship behind all the 2D observations, -and infer the rigid scene structure (3D points) with the pose (position and orientation) and internal calibration of all cameras. -The pipeline is a growing reconstruction process (called incremental SfM): it first computes an initial two-view reconstruction that is iteratively extended by adding new views. - -1/ Fuse 2-View Matches into Tracks - -It fuses all feature matches between image pairs into tracks. Each track represents a candidate point in space, visible from multiple cameras. -However, at this step of the pipeline, it still contains many outliers. - -2/ Initial Image Pair - -It chooses the best initial image pair. This choice is critical for the quality of the final reconstruction. -It should indeed provide robust matches and contain reliable geometric information. -So, this image pair should maximize the number of matches and the repartition of the corresponding features in each image. -But at the same time, the angle between the cameras should also be large enough to provide reliable geometric information. - -3/ Initial 2-View Geometry - -It computes the fundamental matrix between the 2 images selected and consider that the first one is the origin of the coordinate system. - -4/ Triangulate - -Now with the pose of the 2 first cameras, it triangulates the corresponding 2D features into 3D points. - -5/ Next Best View Selection - -After that, it selects all the images that have enough associations with the features that are already reconstructed in 3D. - -6/ Estimate New Cameras - -Based on these 2D-3D associations it performs the resectioning of each of these new cameras. -The resectioning is a Perspective-n-Point algorithm (PnP) in a RANSAC framework to find the pose of the camera that validates most of the features associations. -On each camera, a non-linear minimization is performed to refine the pose. - -7/ Triangulate - -From these new cameras poses, some tracks become visible by 2 or more resected cameras and it triangulates them. - -8/ Optimize - -It performs a Bundle Adjustment to refine everything: extrinsics and intrinsics parameters of all cameras as well as the position of all 3D points. -It filters the results of the Bundle Adjustment by removing all observations that have high reprojection error or insufficient angles between observations. - -9/ Loop from 5 to 9 - -As we have triangulated new points, we get more image candidates for next best views selection and we can iterate from 5 to 9. -It iterates like that, adding cameras and triangulating new 2D features into 3D points and removing 3D points that became invalidated, until we cannot localize new views. - -## Online -[https://alicevision.org/#photogrammetry/sfm](https://alicevision.org/#photogrammetry/sfm) -''' - - inputs = [ - desc.File( - name="input", - label="SfMData", - description="Input SfMData file.", - value="", - ), - desc.ListAttribute( - elementDesc=desc.File( - name="featuresFolder", - label="Features Folder", - description="", - value="", - ), - name="featuresFolders", - label="Features Folders", - description="Folder(s) containing the extracted features and descriptors.", - exposed=True, - ), - desc.ListAttribute( - elementDesc=desc.File( - name="matchesFolder", - label="Matches Folder", - description="", - value="", - ), - name="matchesFolders", - label="Matches Folders", - description="Folder(s) in which the computed matches are stored.", - exposed=True, - ), - desc.ChoiceParam( - name="describerTypes", - label="Describer Types", - description="Describer types used to describe an image.", - values=DESCRIBER_TYPES, - value=["dspsift"], - exclusive=False, - joinChar=",", - exposed=True, - ), - desc.ChoiceParam( - name="localizerEstimator", - label="Localizer Estimator", - description="Estimator type used to localize cameras (acransac, ransac, lsmeds, loransac, maxconsensus).", - value="acransac", - values=["acransac", "ransac", "lsmeds", "loransac", "maxconsensus"], - advanced=True, - ), - desc.ChoiceParam( - name="observationConstraint", - label="Observation Constraint", - description="Observation constraint mode used in the optimization:\n" - " - Basic: Use standard reprojection error in pixel coordinates.\n" - " - Scale: Use reprojection error in pixel coordinates but relative to the feature scale.", - value="Scale", - values=["Basic", "Scale"], - advanced=True, - ), - desc.IntParam( - name="localizerEstimatorMaxIterations", - label="Localizer Max Ransac Iterations", - description="Maximum number of iterations allowed in the Ransac step.", - value=50000, - range=(1, 100000, 1), - advanced=True, - ), - desc.FloatParam( - name="localizerEstimatorError", - label="Localizer Max Ransac Error", - description="Maximum error (in pixels) allowed for camera localization (resectioning).\n" - "If set to 0, it will select a threshold according to the localizer estimator used\n" - "(if ACRansac, it will analyze the input data to select the optimal value).", - value=0.0, - range=(0.0, 100.0, 0.1), - advanced=True, - ), - desc.BoolParam( - name="lockScenePreviouslyReconstructed", - label="Lock Previously Reconstructed Scene", - description="Lock previously reconstructed poses and intrinsics.\n" - "This option is useful for SfM augmentation.", - value=False, - ), - desc.BoolParam( - name="useLocalBA", - label="Local Bundle Adjustment", - description="It reduces the reconstruction time, especially for large datasets (500+ images),\n" - "by avoiding computation of the Bundle Adjustment on areas that are not changing.", - value=True, - ), - desc.IntParam( - name="localBAGraphDistance", - label="LocalBA Graph Distance", - description="Graph-distance limit to define the active region in the Local Bundle Adjustment strategy.", - value=1, - range=(2, 10, 1), - advanced=True, - ), - desc.IntParam( - name="nbFirstUnstableCameras", - label="First Unstable Cameras Nb", - description="Number of cameras for which the bundle adjustment is performed every single time a camera is added.\n" - "This leads to more stable results while computations are not too expensive, as there is little data.\n" - "Past this number, the bundle adjustment will only be performed once for N added cameras.", - value=30, - range=(0, 100, 1), - advanced=True, - ), - desc.IntParam( - name="maxImagesPerGroup", - label="Max Images Per Group", - description="Maximum number of cameras that can be added before the bundle adjustment has to be performed again.\n" - "This prevents adding too much data at once without performing the bundle adjustment.", - value=30, - range=(0, 100, 1), - advanced=True, - ), - desc.IntParam( - name="bundleAdjustmentMaxOutliers", - label="Max Nb Of Outliers After BA", - description="Threshold for the maximum number of outliers allowed at the end of a bundle adjustment iteration.\n" - "Using a negative value for this threshold will disable BA iterations.", - value=50, - range=(-1, 1000, 1), - advanced=True, - ), - desc.IntParam( - name="maxNumberOfMatches", - label="Maximum Number Of Matches", - description="Maximum number of matches per image pair (and per feature type).\n" - "This can be useful to have a quick reconstruction overview.\n" - "0 means no limit.", - value=0, - range=(0, 50000, 1), - ), - desc.IntParam( - name="minNumberOfMatches", - label="Minimum Number Of Matches", - description="Minimum number of matches per image pair (and per feature type).\n" - "This can be useful to have a meaningful reconstruction with accurate keypoints.\n" - "0 means no limit.", - value=0, - range=(0, 50000, 1), - ), - desc.IntParam( - name="minInputTrackLength", - label="Min Input Track Length", - description="Minimum track length in input of SfM.", - value=2, - range=(2, 10, 1), - ), - desc.IntParam( - name="minNumberOfObservationsForTriangulation", - label="Min Observations For Triangulation", - description="Minimum number of observations to triangulate a point.\n" - "Setting it to 3 (or more) reduces drastically the noise in the point cloud,\n" - "but the number of final poses is a little bit reduced\n" - "(from 1.5% to 11% on the tested datasets).", - value=2, - range=(2, 10, 1), - advanced=True, - ), - desc.FloatParam( - name="minAngleForTriangulation", - label="Min Angle For Triangulation", - description="Minimum angle for triangulation.", - value=3.0, - range=(0.1, 10.0, 0.1), - advanced=True, - ), - desc.FloatParam( - name="minAngleForLandmark", - label="Min Angle For Landmark", - description="Minimum angle for landmark.", - value=2.0, - range=(0.1, 10.0, 0.1), - advanced=True, - ), - desc.FloatParam( - name="maxReprojectionError", - label="Max Reprojection Error", - description="Maximum reprojection error.", - value=4.0, - range=(0.1, 10.0, 0.1), - advanced=True, - ), - desc.FloatParam( - name="minAngleInitialPair", - label="Min Angle Initial Pair", - description="Minimum angle for the initial pair.", - value=5.0, - range=(0.1, 10.0, 0.1), - advanced=True, - ), - desc.FloatParam( - name="maxAngleInitialPair", - label="Max Angle Initial Pair", - description="Maximum angle for the initial pair.", - value=40.0, - range=(0.1, 60.0, 0.1), - advanced=True, - ), - desc.BoolParam( - name="useOnlyMatchesFromInputFolder", - label="Use Only Matches From Input Folder", - description="Use only matches from the input matchesFolder parameter.\n" - "Matches folders previously added to the SfMData file will be ignored.", - value=False, - invalidate=False, - advanced=True, - ), - desc.BoolParam( - name="useRigConstraint", - label="Use Rig Constraint", - description="Enable/Disable rig constraint.", - value=True, - advanced=True, - ), - desc.IntParam( - name="rigMinNbCamerasForCalibration", - label="Min Nb Cameras For Rig Calibration", - description="Minimum number of cameras to start the calibration of the rig.", - value=20, - range=(1, 50, 1), - advanced=True, - ), - desc.BoolParam( - name="lockAllIntrinsics", - label="Lock All Intrinsic Camera Parameters", - description="Force to keep all the intrinsic parameters of the cameras (focal length, \n" - "principal point, distortion if any) constant during the reconstruction.\n" - "This may be helpful if the input cameras are already fully calibrated.", - value=False, - ), - desc.IntParam( - name="minNbCamerasToRefinePrincipalPoint", - label="Min Nb Cameras To Refine Principal Point", - description="Minimum number of cameras to refine the principal point of the cameras (one of the intrinsic parameters of the camera).\n" - "If we do not have enough cameras, the principal point is considered to be in the center of the image.\n" - "If minNbCamerasToRefinePrincipalPoint <= 0, the principal point is never refined." - "If minNbCamerasToRefinePrincipalPoint is set to 1, the principal point is always refined.", - value=3, - range=(0, 20, 1), - advanced=True, - ), - desc.BoolParam( - name="filterTrackForks", - label="Filter Track Forks", - description="Enable/Disable the track forks removal. A track contains a fork when incoherent matches \n" - "lead to multiple features in the same image for a single track.", - value=False, - ), - desc.BoolParam( - name="computeStructureColor", - label="Compute Structure Color", - description="Enable/Disable color computation of every 3D point.", - value=True, - ), - desc.BoolParam( - name="useAutoTransform", - label="Automatic Alignment", - description="Enable/Disable automatic alignment of the 3D reconstruction.\n" - "Determines scene orientation from the cameras' X axis,\n" - "determines north and scale from GPS information if available,\n" - "and defines ground level from the point cloud.", - value=True, - ), - desc.File( - name="initialPairA", - label="Initial Pair A", - description="View ID or filename of the first image (either with or without the full path).", - value="", - ), - desc.File( - name="initialPairB", - label="Initial Pair B", - description="View ID or filename of the second image (either with or without the full path).", - value="", - ), - desc.ChoiceParam( - name="interFileExtension", - label="Inter File Extension", - description="Extension of the intermediate file export.", - value=".abc", - values=[".abc", ".ply"], - invalidate=False, - advanced=True, - ), - desc.BoolParam( - name="logIntermediateSteps", - label="Log Intermediate Steps", - description="Dump the current state of the scene as an SfMData file every 3 resections.", - value=False, - invalidate=False, - advanced=True, - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="output", - label="SfMData", - description="Path to the output SfM point cloud file (in SfMData format).", - value="{nodeCacheFolder}/sfm.abc", - ), - desc.File( - name="outputViewsAndPoses", - label="Views And Poses", - description="Path to the output SfMData file with cameras (views and poses).", - value="{nodeCacheFolder}/cameras.sfm", - ), - desc.File( - name="extraInfoFolder", - label="Folder", - description="Folder for intermediate reconstruction files and additional reconstruction information files.", - value="{nodeCacheFolder}", - ), - ] diff --git a/meshroom/nodes/aliceVision/Texturing.py b/meshroom/nodes/aliceVision/Texturing.py deleted file mode 100644 index 87295bf877..0000000000 --- a/meshroom/nodes/aliceVision/Texturing.py +++ /dev/null @@ -1,371 +0,0 @@ -__version__ = "6.0" - -from meshroom.core import desc, Version -from meshroom.core.utils import COLORSPACES, VERBOSE_LEVEL - -import logging - - -class Texturing(desc.AVCommandLineNode): - commandLine = 'aliceVision_texturing {allParams}' - cpu = desc.Level.INTENSIVE - ram = desc.Level.INTENSIVE - - category = 'Dense Reconstruction' - documentation = ''' -This node computes the texturing on the mesh. - -If the mesh has no associated UV, it automatically computes UV maps. - -For each triangle, it uses the visibility information associated to each vertex to retrieve the texture candidates. -It select the best cameras based on the resolution covering the triangle. Finally it averages the pixel values using multiple bands in the frequency domain. -Many cameras are contributing to the low frequencies and only the best ones contributes to the high frequencies. - -## Online -[https://alicevision.org/#photogrammetry/texturing](https://alicevision.org/#photogrammetry/texturing) -''' - - inputs = [ - desc.File( - name="input", - label="Dense SfMData", - description="SfMData file.", - value="", - ), - desc.File( - name="imagesFolder", - label="Images Folder", - description="Use images from a specific folder instead of those specified in the SfMData file.\n" - "Filename should be the image UID.", - value="", - ), - desc.File( - name="normalsFolder", - label="Normals Folder", - description="Use normal maps from a specific folder to texture the mesh.\nFilename should be : uid_normalMap.", - value="", - ), - desc.File( - name="inputMesh", - label="Mesh", - description="Optional input mesh to texture. By default, it will texture the result of the reconstruction.", - value="", - ), - desc.File( - name="inputRefMesh", - label="Ref Mesh", - description="Optional input mesh to compute height maps and normal maps.\n" - "If not provided, no additional map with geometric information will be generated.", - value="", - ), - desc.ChoiceParam( - name="textureSide", - label="Texture Side", - description="Output texture size.", - value=8192, - values=[1024, 2048, 4096, 8192, 16384], - ), - desc.ChoiceParam( - name="downscale", - label="Texture Downscale", - description="Texture downscale factor.", - value=2, - values=[1, 2, 4, 8], - ), - desc.ChoiceParam( - name="outputMeshFileType", - label="Mesh File Type", - description="File type for the mesh output.", - value="obj", - values=["obj", "gltf", "fbx", "stl"], - ), - desc.GroupAttribute( - name="colorMapping", - label="Color Mapping", - description="Color map parameters.", - enabled=lambda node: (node.imagesFolder.value != ''), - group=None, - groupDesc=[ - desc.BoolParam( - name="enable", - label="Enable", - description="Generate textures if set to true.", - value=True, - invalidate=False, - group=None, - ), - desc.ChoiceParam( - name="colorMappingFileType", - label="File Type", - description="Texture file type.", - value="exr", - values=["exr", "png", "tiff", "jpg"], - enabled=lambda node: node.colorMapping.enable.value, - ), - ], - ), - desc.GroupAttribute( - name="bumpMapping", - label="Bump Mapping", - description="Bump mapping parameters.", - enabled=lambda node: (node.inputRefMesh.value != ''), - group=None, - groupDesc=[ - desc.BoolParam( - name="enable", - label="Enable", - description="Generate normal / bump maps if set to true.", - value=True, - invalidate=False, - group=None, - ), - desc.ChoiceParam( - name="bumpType", - label="Bump Type", - description="Export normal map or height map.", - value="Normal", - values=["Height", "Normal"], - enabled=lambda node: node.bumpMapping.enable.value, - ), - desc.ChoiceParam( - name="normalFileType", - label="File Type", - description="File type for the normal map texture.", - value="exr", - values=["exr", "png", "tiff", "jpg"], - enabled=lambda node: node.bumpMapping.enable.value and node.bumpMapping.bumpType.value == "Normal", - ), - desc.ChoiceParam( - name="heightFileType", - label="File Type", - description="File type for the height map texture.", - value="exr", - values=["exr",], - enabled=lambda node: node.bumpMapping.enable.value and node.bumpMapping.bumpType.value == "Height", - ), - ], - ), - desc.GroupAttribute( - name="displacementMapping", - label="Displacement Mapping", - description="Displacement mapping parameters.", - enabled=lambda node: (node.inputRefMesh.value != ""), - group=None, - groupDesc=[ - desc.BoolParam( - name="enable", - label="Enable", - description="Generate height maps for displacement.", - value=True, - invalidate=False, - group=None, - ), - desc.ChoiceParam( - name="displacementMappingFileType", - label="File Type", - description="File type for the height map texture.", - value="exr", - values=["exr"], - enabled=lambda node: node.displacementMapping.enable.value, - ), - ], - ), - desc.ChoiceParam( - name="unwrapMethod", - label="Unwrap Method", - description="Method to unwrap input mesh if it does not have UV coordinates.\n" - " - Basic (> 600k faces) fast and simple. Can generate multiple atlases.\n" - " - LSCM (<= 600k faces): optimize space. Generates one atlas.\n" - " - ABF (<= 300k faces): optimize space and stretch. Generates one atlas.", - value="Basic", - values=["Basic", "LSCM", "ABF"], - ), - desc.BoolParam( - name="useUDIM", - label="Use UDIM", - description="Use UDIM UV mapping.", - value=True, - ), - desc.BoolParam( - name="fillHoles", - label="Fill Holes", - description="Fill texture holes with plausible values.", - value=False, - ), - desc.IntParam( - name="padding", - label="Padding", - description="Texture edge padding size in pixels.", - value=5, - range=(0, 20, 1), - advanced=True, - ), - desc.IntParam( - name="multiBandDownscale", - label="Multi Band Downscale", - description="Width of frequency bands for multiband blending.", - value=4, - range=(0, 8, 2), - advanced=True, - ), - desc.GroupAttribute( - name="multiBandNbContrib", - label="Multi-Band Contributions", - groupDesc=[ - desc.IntParam( - name="high", - label="High Freq", - description="High frequency band.", - value=1, - range=None, - ), - desc.IntParam( - name="midHigh", - label="Mid-High Freq", - description="Mid-high frequency band.", - value=5, - range=None, - ), - desc.IntParam( - name="midLow", - label="Mid-Low Freq", - description="Mid-low frequency band.", - value=10, - range=None, - ), - desc.IntParam( - name="low", - label="Low Freq", - description="Low frequency band", - value=0, - range=None, - ), - ], - description="Number of contributions per frequency band for multi-band blending (each frequency band also contributes to lower bands).", - advanced=True, - ), - desc.BoolParam( - name="useScore", - label="Use Score", - description="Use triangles scores (ie. reprojection area) for multi-band blending.", - value=True, - advanced=True, - ), - desc.FloatParam( - name="bestScoreThreshold", - label="Best Score Threshold", - description="Setting this parameter to 0.0 disables filtering based on threshold to relative best score.", - value=0.1, - range=(0.0, 1.0, 0.01), - advanced=True, - ), - desc.FloatParam( - name="angleHardThreshold", - label="Angle Hard Threshold", - description="Setting this parameter to 0.0 disables angle hard threshold filtering.", - value=90.0, - range=(0.0, 180.0, 0.01), - advanced=True, - ), - desc.ChoiceParam( - name="workingColorSpace", - label="Working Color Space", - description="Color space for the texturing internal computation (does not impact the output file color space).", - values=COLORSPACES, - value="sRGB", - advanced=True, - ), - desc.ChoiceParam( - name="outputColorSpace", - label="Output Color Space", - description="Color space for the output texture files.", - values=COLORSPACES, - value="AUTO", - ), - desc.BoolParam( - name="correctEV", - label="Correct Exposure", - description="Uniformize images exposure values.", - value=True, - ), - desc.BoolParam( - name="forceVisibleByAllVertices", - label="Force Visible By All Vertices", - description="Triangle visibility is based on the union of vertices visibility.", - value=False, - advanced=True, - ), - desc.BoolParam( - name="flipNormals", - label="Flip Normals", - description="Option to flip face normals.\n" - "It can be needed as it depends on the vertices order in triangles and the convention changes from one software to another.", - value=False, - advanced=True, - ), - desc.ChoiceParam( - name="visibilityRemappingMethod", - label="Visibility Remapping Method", - description="Method to remap visibilities from the reconstruction to the input mesh (Pull, Push, PullPush, MeshItself).", - value="PullPush", - values=["Pull", "Push", "PullPush", "MeshItself"], - advanced=True, - ), - desc.FloatParam( - name="subdivisionTargetRatio", - label="Subdivision Target Ratio", - description="Percentage of the density of the reconstruction as the target for the subdivision:\n" - " - 0: disable subdivision.\n" - " - 0.5: half density of the reconstruction.\n" - " - 1: full density of the reconstruction).", - value=0.8, - range=(0.0, 1.0, 0.001), - advanced=True, - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="output", - label="Folder", - description="Folder for output mesh: OBJ, material and texture files.", - value="{nodeCacheFolder}", - ), - desc.File( - name="outputMesh", - label="Mesh", - description="Output mesh file.", - value="{nodeCacheFolder}/texturedMesh.{outputMeshFileTypeValue}", - group="", - ), - desc.File( - name="outputMaterial", - enabled=lambda node: node.outputMeshFileType.value == "obj", - label="Material", - description="Output material file.", - value="{nodeCacheFolder}/texturedMesh.mtl", - group="", - ), - desc.File( - name="outputTextures", - label="Textures", - description="Output texture files.", - value=lambda attr: "{nodeCacheFolder}/texture_*." + attr.node.colorMapping.colorMappingFileType.value if attr.node.colorMapping.enable.value else "", - group="", - ), - ] - - def upgradeAttributeValues(self, attrValues, fromVersion): - if fromVersion < Version(6, 0): - outputTextureFileType = attrValues["outputTextureFileType"] - if isinstance(outputTextureFileType, str): - attrValues["colorMapping"] = {} - attrValues["colorMapping"]["colorMappingFileType"] = outputTextureFileType - return attrValues diff --git a/meshroom/nodes/aliceVision/TracksBuilding.py b/meshroom/nodes/aliceVision/TracksBuilding.py deleted file mode 100644 index 1a52185545..0000000000 --- a/meshroom/nodes/aliceVision/TracksBuilding.py +++ /dev/null @@ -1,97 +0,0 @@ -__version__ = "1.0" - -from meshroom.core import desc -from meshroom.core.utils import DESCRIBER_TYPES, VERBOSE_LEVEL - - -class TracksBuilding(desc.AVCommandLineNode): - commandLine = 'aliceVision_tracksBuilding {allParams}' - size = desc.DynamicNodeSize('input') - - category = 'Sparse Reconstruction' - documentation = ''' -It fuses all feature matches between image pairs into tracks. Each track represents a candidate point in space, visible from multiple cameras. -''' - - inputs = [ - desc.File( - name="input", - label="SfMData", - description="Input SfMData file.", - value="", - exposed=True, - ), - desc.ListAttribute( - elementDesc=desc.File( - name="featuresFolder", - label="Features Folder", - description="Folder containing some extracted features and descriptors.", - value="", - ), - name="featuresFolders", - label="Features Folders", - description="Folder(s) containing the extracted features and descriptors.", - exposed=True, - ), - desc.ListAttribute( - elementDesc=desc.File( - name="matchesFolder", - label="Matches Folder", - description="Folder containing some matches.", - value="", - ), - name="matchesFolders", - label="Matches Folders", - description="Folder(s) in which computed matches are stored.", - exposed=True, - ), - desc.ChoiceParam( - name="describerTypes", - label="Describer Types", - description="Describer types used to describe an image.", - values=DESCRIBER_TYPES, - value=["dspsift"], - exclusive=False, - joinChar=",", - exposed=True, - ), - desc.IntParam( - name="minInputTrackLength", - label="Min Input Track Length", - description="Minimum track length.", - value=2, - range=(2, 10, 1), - ), - desc.BoolParam( - name="useOnlyMatchesFromInputFolder", - label="Use Only Matches From Input Folder", - description="Use only matches from the input 'matchesFolder' parameter.\n" - "Matches folders previously added to the SfMData file will be ignored.", - value=False, - invalidate=False, - advanced=True, - ), - desc.BoolParam( - name="filterTrackForks", - label="Filter Track Forks", - description="Enable/Disable the track forks removal. A track contains a fork when incoherent matches\n" - "lead to multiple features in the same image for a single track.", - value=False, - ), - desc.ChoiceParam( - name="verboseLevel", - label="Verbose Level", - description="Verbosity level (fatal, error, warning, info, debug, trace).", - values=VERBOSE_LEVEL, - value="info", - ), - ] - - outputs = [ - desc.File( - name="output", - label="Tracks", - description="Path to the output tracks file.", - value="{nodeCacheFolder}/tracksFile.json", - ), - ] diff --git a/meshroom/nodes/aliceVision/__init__.py b/meshroom/nodes/aliceVision/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/meshroom/nodes/blender/ScenePreview.py b/meshroom/nodes/blender/ScenePreview.py deleted file mode 100644 index 154a841e3c..0000000000 --- a/meshroom/nodes/blender/ScenePreview.py +++ /dev/null @@ -1,141 +0,0 @@ -__version__ = "2.0" - -from meshroom.core import desc -import os.path - -currentDir = os.path.dirname(os.path.abspath(__file__)) - -class ScenePreview(desc.CommandLineNode): - commandLine = '{blenderCmdValue} -b --python {scriptValue} -- {allParams}' - size = desc.DynamicNodeSize('cameras') - parallelization = desc.Parallelization(blockSize=40) - commandLineRange = '--rangeStart {rangeStart} --rangeSize {rangeBlockSize}' - - category = 'Utils' - documentation = ''' -This node uses Blender to visualize a 3D model from a given set of cameras. -The cameras must be a SfMData file in JSON format. -For the 3D model it supports both point clouds in Alembic format and meshes in OBJ format. -One frame per viewpoint will be rendered, and the undistorted views can optionally be used as background. -''' - - inputs = [ - desc.File( - name="blenderCmd", - label="Blender Command", - description="Command to launch Blender.", - value="blender", - invalidate=False, - group="", - ), - desc.File( - name="script", - label="Script", - description="Path to the internal script for rendering in Blender.", - value=os.path.join("{nodeSourceCodeFolder}", "scripts", "preview.py"), - invalidate=False, - group="", - advanced=True, - ), - desc.File( - name="cameras", - label="Cameras", - description="SfMData with the views, poses and intrinsics to use (in JSON format).", - value="", - ), - desc.File( - name="model", - label="Model", - description="Point cloud (.abc) or mesh (.obj) to render.", - value="", - ), - desc.BoolParam( - name="useBackground", - label="Display Background", - description="Use the undistorted images as background.", - value=True, - ), - desc.File( - name="undistortedImages", - label="Undistorted Images", - description="Folder containing the undistorted images.", - value="", - enabled=lambda node: node.useBackground.value, - ), - desc.BoolParam( - name="useMasks", - label="Apply Masks", - description="Apply mask to the rendered geometry.", - value=True, - ), - desc.File( - name="masks", - label="Masks", - description="Folder containing the masks.", - value="", - enabled=lambda node: node.useMasks.value, - ), - desc.GroupAttribute( - name="pointCloudParams", - label="Point Cloud Settings", - group=None, - enabled=lambda node: node.model.value.lower().endswith(".abc"), - description="Settings for point cloud rendering.", - groupDesc=[ - desc.FloatParam( - name="particleSize", - label="Particle Size", - description="Scale of particles used for the point cloud.", - value=0.01, - range=(0.01, 1.0, 0.01), - ), - desc.ChoiceParam( - name="particleColor", - label="Particle Color", - description="Color of particles used for the point cloud.", - value="Red", - values=["Grey", "White", "Red", "Green", "Magenta"], - ), - ], - ), - desc.GroupAttribute( - name="meshParams", - label="Mesh Settings", - group=None, - enabled=lambda node: node.model.value.lower().endswith(".obj"), - description="Setting for mesh rendering.", - groupDesc=[ - desc.ChoiceParam( - name="shading", - label="Shading", - description="Shading method for visualizing the mesh.", - value="wireframe", - values=["wireframe", "line_art"], - ), - desc.ChoiceParam( - name="edgeColor", - label="Edge Color", - description="Color of the mesh edges.", - value="Red", - values=["Grey", "White", "Red", "Green", "Magenta"], - ), - ], - ), - ] - - outputs = [ - desc.File( - name="output", - label="Output", - description="Output folder.", - value="{nodeCacheFolder}", - ), - desc.File( - name="frames", - label="Frames", - description="Frames rendered in Blender.", - semantic="image", - value="{nodeCacheFolder}/_preview.jpg", - group="", - ), - ] diff --git a/meshroom/nodes/blender/__init__.py b/meshroom/nodes/blender/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/meshroom/nodes/blender/scripts/__init__.py b/meshroom/nodes/blender/scripts/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/meshroom/nodes/blender/scripts/preview.py b/meshroom/nodes/blender/scripts/preview.py deleted file mode 100644 index ba4d431860..0000000000 --- a/meshroom/nodes/blender/scripts/preview.py +++ /dev/null @@ -1,434 +0,0 @@ -import bpy -import os -import mathutils -import math -import sys -import argparse -import json -import glob - - -def createParser(): - '''Create command line interface.''' - # When --help or no args are given, print this help - usage_text = ( - "Run blender in background mode with this script:" - " blender --background --python " + __file__ + " -- [options]" - ) - - parser = argparse.ArgumentParser(description=usage_text) - - parser.add_argument( - "--cameras", metavar='FILE', required=True, - help="sfmData with the animated camera.", - ) - parser.add_argument( - "--rangeStart", type=int, required=False, default=-1, - help="Range start for processing views. Set to -1 to process all views.", - ) - parser.add_argument( - "--rangeSize", type=int, required=False, default=0, - help="Range size for processing views.", - ) - parser.add_argument( - "--useBackground", type=lambda x: (str(x).lower() == 'true'), required=True, - help="Display the background image or not.", - ) - parser.add_argument( - "--undistortedImages", metavar='FILE', required=False, - help="Path to folder containing undistorted images to use as background.", - ) - parser.add_argument( - "--model", metavar='FILE', required=True, - help="Point Cloud or Mesh used in the rendering.", - ) - parser.add_argument( - "--useMasks", type=lambda x: (str(x).lower() == 'true'), required=True, - help="Apply mask to the rendered geometry or not.", - ) - parser.add_argument( - "--masks", metavar='FILE', required=False, - help="Path to folder containing masks to apply on rendered geometry.", - ) - parser.add_argument( - "--particleSize", type=float, required=False, - help="Scale of particles used to show the point cloud", - ) - parser.add_argument( - "--particleColor", type=str, required=False, - help="Color of particles used to show the point cloud (SFM Data is .abc)", - ) - parser.add_argument( - "--edgeColor", type=str, required=False, - help="Color of the edges of the rendered object (SFM Data is .obj)", - ) - parser.add_argument( - "--shading", type=str, required=False, - help="Shading method for rendering the mesh", - ) - parser.add_argument( - "--output", metavar='FILE', required=True, - help="Render an image to the specified path", - ) - - return parser - - -def parseSfMCameraFile(filepath): - '''Retrieve cameras from SfM file in json format.''' - with open(os.path.abspath(filepath), 'r') as file: - sfm = json.load(file) - views = sfm['views'] - intrinsics = sfm['intrinsics'] - poses = sfm['poses'] - return views, intrinsics, poses - - -def getFromId(data, key, identifier): - '''Utility function to retrieve view, intrinsic or pose using their IDs.''' - for item in data: - if item[key] == identifier: - return item - return None - - -def setupCamera(intrinsic, pose): - '''Setup Blender camera to match the given SfM camera.''' - camObj = bpy.data.objects['Camera'] - camData = bpy.data.cameras['Camera'] - - bpy.context.scene.render.resolution_x = int(intrinsic['width']) - bpy.context.scene.render.resolution_y = int(intrinsic['height']) - bpy.context.scene.render.pixel_aspect_x = float(intrinsic['pixelRatio']) - - camData.sensor_width = float(intrinsic['sensorWidth']) - camData.lens = float(intrinsic['focalLength']) / float(intrinsic['pixelRatio']) - - #shift is normalized with the largest resolution - fwidth = float(intrinsic['width']) - fheight = float(intrinsic['height']) - maxSize = max(fwidth, fheight) - camData.shift_x = - float(intrinsic['principalPoint'][0]) / maxSize - camData.shift_y = float(intrinsic['principalPoint'][1]) / maxSize - - tr = pose['pose']['transform'] - matPose = mathutils.Matrix.Identity(4) - matPose[0][0] = float(tr['rotation'][0]) - matPose[0][1] = float(tr['rotation'][1]) - matPose[0][2] = float(tr['rotation'][2]) - matPose[1][0] = float(tr['rotation'][3]) - matPose[1][1] = float(tr['rotation'][4]) - matPose[1][2] = float(tr['rotation'][5]) - matPose[2][0] = float(tr['rotation'][6]) - matPose[2][1] = float(tr['rotation'][7]) - matPose[2][2] = float(tr['rotation'][8]) - matPose[0][3] = float(tr['center'][0]) - matPose[1][3] = float(tr['center'][1]) - matPose[2][3] = float(tr['center'][2]) - - matConvert = mathutils.Matrix.Identity(4) - matConvert[1][1] = -1 - matConvert[2][2] = -1 - - camObj.matrix_world = matConvert @ matPose @ matConvert - - -def initScene(): - '''Initialize Blender scene.''' - # Clear current scene (keep default camera) - bpy.data.objects.remove(bpy.data.objects['Cube']) - bpy.data.objects.remove(bpy.data.objects['Light']) - # Set output format - bpy.context.scene.render.image_settings.file_format = 'JPEG' - # Setup rendering engine - bpy.context.scene.render.engine = 'CYCLES' - bpy.context.scene.cycles.samples = 1 - bpy.context.scene.cycles.use_adaptative_sampling = False - bpy.context.scene.cycles.use_denoising = False - - -def initCompositing(useBackground, useMasks): - '''Initialize Blender compositing graph for adding background image to render.''' - bpy.context.scene.render.film_transparent = True - bpy.context.scene.use_nodes = True - nodeAlphaOver = bpy.context.scene.node_tree.nodes.new(type="CompositorNodeAlphaOver") - nodeSetAlpha = bpy.context.scene.node_tree.nodes.new(type="CompositorNodeSetAlpha") - nodeBackground = bpy.context.scene.node_tree.nodes.new(type="CompositorNodeImage") - nodeMask = bpy.context.scene.node_tree.nodes.new(type="CompositorNodeImage") - nodeRender = bpy.context.scene.node_tree.nodes['Render Layers'] - nodeComposite = bpy.context.scene.node_tree.nodes['Composite'] - if useBackground and useMasks: - bpy.context.scene.node_tree.links.new(nodeBackground.outputs['Image'], nodeAlphaOver.inputs[1]) - bpy.context.scene.node_tree.links.new(nodeRender.outputs['Image'], nodeSetAlpha.inputs['Image']) - bpy.context.scene.node_tree.links.new(nodeMask.outputs['Image'], nodeSetAlpha.inputs['Alpha']) - bpy.context.scene.node_tree.links.new(nodeSetAlpha.outputs['Image'], nodeAlphaOver.inputs[2]) - bpy.context.scene.node_tree.links.new(nodeAlphaOver.outputs['Image'], nodeComposite.inputs['Image']) - elif useBackground: - bpy.context.scene.node_tree.links.new(nodeBackground.outputs['Image'], nodeAlphaOver.inputs[1]) - bpy.context.scene.node_tree.links.new(nodeRender.outputs['Image'], nodeAlphaOver.inputs[2]) - bpy.context.scene.node_tree.links.new(nodeAlphaOver.outputs['Image'], nodeComposite.inputs['Image']) - elif useMasks: - bpy.context.scene.node_tree.links.new(nodeRender.outputs['Image'], nodeSetAlpha.inputs['Image']) - bpy.context.scene.node_tree.links.new(nodeMask.outputs['Image'], nodeSetAlpha.inputs['Alpha']) - bpy.context.scene.node_tree.links.new(nodeSetAlpha.outputs['Image'], nodeComposite.inputs['Image']) - return nodeBackground, nodeMask - - -def setupRender(view, intrinsic, pose, outputDir): - '''Setup rendering in Blender for a given view.''' - setupCamera(intrinsic, pose) - - baseImgName = os.path.splitext(os.path.basename(view['path']))[0] - bpy.context.scene.render.filepath = os.path.abspath(outputDir + '/' + baseImgName + '_preview.jpg') - - -def setupBackground(view, folderUndistorted, nodeBackground): - '''Retrieve undistorted image corresponding to view and use it as background.''' - matches = glob.glob(folderUndistorted + '/*' + view['viewId'] + "*") # try with viewId - if len(matches) == 0: - baseImgName = os.path.splitext(os.path.basename(view['path']))[0] - matches = glob.glob(folderUndistorted + '/*' + baseImgName + "*") # try with image name - if len(matches) == 0: - # no background image found - return None - undistortedImgPath = matches[0] - img = bpy.data.images.load(filepath=undistortedImgPath) - nodeBackground.image = img - return img - - -def setupMask(view, folderMasks, nodeMask): - '''Retrieve mask corresponding to view and use it in compositing graph.''' - matches = glob.glob(folderMasks + '/*' + view['viewId'] + "*") # try with viewId - if len(matches) == 0: - baseImgName = os.path.splitext(os.path.basename(view['path']))[0] - matches = glob.glob(folderMasks + '/*' + baseImgName + "*") # try with image name - if len(matches) == 0: - # no background image found - return None - maskPath = matches[0] - mask = bpy.data.images.load(filepath=maskPath) - nodeMask.image = mask - return mask - - -def loadModel(filename): - '''Load model in Alembic of OBJ format. Make sure orientation matches camera orientation.''' - if filename.lower().endswith('.obj'): - bpy.ops.import_scene.obj(filepath=filename, axis_forward='Y', axis_up='Z') - meshName = os.path.splitext(os.path.basename(filename))[0] - return bpy.data.objects[meshName], bpy.data.meshes[meshName] - elif filename.lower().endswith('.abc'): - bpy.ops.wm.alembic_import(filepath=filename) - root = bpy.data.objects['mvgRoot'] - root.rotation_euler.rotate_axis('X', math.radians(-90.0)) - return bpy.data.objects['mvgPointCloud'], bpy.data.meshes['particleShape1'] - - -def setupWireframeShading(mesh, color): - '''Setup material for wireframe shading.''' - # Initialize wireframe material - material = bpy.data.materials.new('Wireframe') - material.use_backface_culling = True - material.use_nodes = True - material.blend_method = 'BLEND' - material.node_tree.links.clear() - # Wireframe node - nodeWireframe = material.node_tree.nodes.new(type='ShaderNodeWireframe') - nodeWireframe.use_pixel_size = True - nodeWireframe.inputs['Size'].default_value = 2.0 - # Emission node - nodeEmission = material.node_tree.nodes.new(type='ShaderNodeEmission') - nodeEmission.inputs['Color'].default_value = color - # Holdout node - nodeHoldout = material.node_tree.nodes.new(type='ShaderNodeHoldout') - # Max Shader node - nodeMix = material.node_tree.nodes.new(type='ShaderNodeMixShader') - # Retrieve ouput node - nodeOutput = material.node_tree.nodes['Material Output'] - # Connect nodes - material.node_tree.links.new(nodeWireframe.outputs['Fac'], nodeMix.inputs['Fac']) - material.node_tree.links.new(nodeHoldout.outputs['Holdout'], nodeMix.inputs[1]) - material.node_tree.links.new(nodeEmission.outputs['Emission'], nodeMix.inputs[2]) - material.node_tree.links.new(nodeMix.outputs['Shader'], nodeOutput.inputs['Surface']) - # Apply material to mesh - mesh.materials.clear() - mesh.materials.append(material) - - -def setupLineArtShading(obj, mesh, color): - '''Setup line art shading using Freestyle.''' - # Freestyle - bpy.context.scene.render.use_freestyle = True - bpy.data.linestyles["LineStyle"].color = (color[0], color[1], color[2]) - # Holdout material - material = bpy.data.materials.new('Holdout') - material.use_nodes = True - material.node_tree.links.clear() - nodeHoldout = material.node_tree.nodes.new(type='ShaderNodeHoldout') - nodeOutput = material.node_tree.nodes['Material Output'] - material.node_tree.links.new(nodeHoldout.outputs['Holdout'], nodeOutput.inputs['Surface']) - # Apply material to mesh - mesh.materials.clear() - mesh.materials.append(material) - - -def setupPointCloudShading(obj, color, size): - '''Setup material and geometry nodes for point cloud shading.''' - # Colored filling material - material = bpy.data.materials.new('PointCloud_Mat') - material.use_nodes = True - material.node_tree.links.clear() - nodeEmission = material.node_tree.nodes.new(type='ShaderNodeEmission') - nodeEmission.inputs['Color'].default_value = color - nodeOutputFill = material.node_tree.nodes['Material Output'] - material.node_tree.links.new(nodeEmission.outputs['Emission'], nodeOutputFill.inputs['Surface']) - # Geometry nodes modifier for particles - geo = bpy.data.node_groups.new('Particles_Graph', type='GeometryNodeTree') - mod = obj.modifiers.new('Particles_Modifier', type='NODES') - mod.node_group = geo - # Setup nodes - nodeInput = geo.nodes.new(type='NodeGroupInput') - nodeOutput = geo.nodes.new(type='NodeGroupOutput') - nodeM2P = geo.nodes.new(type='GeometryNodeMeshToPoints') - nodeIoP = geo.nodes.new(type='GeometryNodeInstanceOnPoints') - nodeCube = geo.nodes.new(type='GeometryNodeMeshCube') - nodeSize = geo.nodes.new(type='ShaderNodeValue') - nodeSize.outputs['Value'].default_value = size - nodeMat = geo.nodes.new(type='GeometryNodeSetMaterial') - nodeMat.inputs[2].default_value = material - # Connect nodes - geo.links.new(nodeInput.outputs[0], nodeM2P.inputs['Mesh']) - geo.links.new(nodeM2P.outputs['Points'], nodeIoP.inputs['Points']) - geo.links.new(nodeCube.outputs['Mesh'], nodeIoP.inputs['Instance']) - geo.links.new(nodeSize.outputs['Value'], nodeIoP.inputs['Scale']) - geo.links.new(nodeIoP.outputs['Instances'], nodeMat.inputs['Geometry']) - geo.links.new(nodeMat.outputs[0], nodeOutput.inputs[0]) - - - -def main(): - - argv = sys.argv - - if "--" not in argv: - argv = [] # as if no args are passed - else: - argv = argv[argv.index("--") + 1:] # get all args after "--" - - parser = createParser() - args = parser.parse_args(argv) - - if not argv: - parser.print_help() - return -1 - - if args.useBackground and not args.undistortedImages: - print("Error: --undistortedImages argument not given, aborting.") - parser.print_help() - return -1 - - # Color palette (common for point cloud and mesh visualization) - palette={ - 'Grey':(0.2, 0.2, 0.2, 1), - 'White':(1, 1, 1, 1), - 'Red':(0.5, 0, 0, 1), - 'Green':(0, 0.5, 0, 1), - 'Magenta':(1.0, 0, 0.75, 1) - } - - print("Init scene") - initScene() - - print("Init compositing") - nodeBackground, nodeMask = initCompositing(args.useBackground, args.useMasks) - - print("Parse cameras SfM file") - views, intrinsics, poses = parseSfMCameraFile(args.cameras) - - print("Load scene objects") - sceneObj, sceneMesh = loadModel(args.model) - - print("Setup shading") - if args.model.lower().endswith('.obj'): - color = palette[args.edgeColor] - if args.shading == 'wireframe': - setupWireframeShading(sceneMesh, color) - elif args.shading == 'line_art': - setupLineArtShading(sceneObj, sceneMesh, color) - elif args.model.lower().endswith('.abc'): - color = palette[args.particleColor] - setupPointCloudShading(sceneObj, color, args.particleSize) - - print("Retrieve range") - rangeStart = args.rangeStart - rangeSize = args.rangeSize - if rangeStart != -1: - if rangeStart < 0 or rangeSize < 0 or rangeStart > len(views): - print("Invalid range") - return 0 - if rangeStart + rangeSize > len(views): - rangeSize = len(views) - rangeStart - else: - rangeStart = 0 - rangeSize = len(views) - - print("Render viewpoints") - for view in views[rangeStart:rangeStart+rangeSize]: - intrinsic = getFromId(intrinsics, 'intrinsicId', view['intrinsicId']) - if not intrinsic: - continue - - pose = getFromId(poses, 'poseId', view['poseId']) - if not pose: - continue - - print("Rendering view " + view['viewId']) - - img = None - if args.useBackground: - img = setupBackground(view, args.undistortedImages, nodeBackground) - if not img: - # background setup failed - # do not render this frame - continue - - mask = None - if args.useMasks: - mask = setupMask(view, args.masks, nodeMask) - if not mask: - # mask setup failed - # do not render this frame - continue - - setupRender(view, intrinsic, pose, args.output) - bpy.ops.render.render(write_still=True) - - # if the pixel aspect ratio is not 1, reload and rescale the rendered image - if bpy.context.scene.render.pixel_aspect_x != 1.0: - finalImg = bpy.data.images.load(bpy.context.scene.render.filepath) - finalImg.scale(int(bpy.context.scene.render.resolution_x * bpy.context.scene.render.pixel_aspect_x), bpy.context.scene.render.resolution_y) - finalImg.save() - # clear image from memory - bpy.data.images.remove(finalImg) - - # clear memory - if img: - bpy.data.images.remove(img) - if mask: - bpy.data.images.remove(mask) - - print("Done") - return 0 - - -if __name__ == "__main__": - - err = 1 - try: - err = main() - except Exception as e: - print("\n" + str(e)) - sys.exit(err) - sys.exit(err) - From f5b79f6d39770f2686a0ee89dd7105cc0e8581c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Candice=20Bent=C3=A9jac?= Date: Mon, 17 Mar 2025 16:47:12 +0100 Subject: [PATCH 4/9] [core] Update `initPipelines` following removal of the "pipelines" folder Since the "pipelines" folder does not exist anymore in Meshroom, there is no use to try and look for any file in it. Instead, we now only look for the paths that have been provided with the `MESHROOM_PIPELINE_TEMPLATES_PATH` environment variable. --- meshroom/core/__init__.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/meshroom/core/__init__.py b/meshroom/core/__init__.py index 3bd30d5bbd..43127b7cd0 100644 --- a/meshroom/core/__init__.py +++ b/meshroom/core/__init__.py @@ -347,13 +347,11 @@ def initSubmitters(): def initPipelines(): meshroomFolder = os.path.dirname(os.path.dirname(__file__)) - # Load pipeline templates: check in the default folder and any folder the user might have - # added to the environment variable - additionalPipelinesPath = os.environ.get("MESHROOM_PIPELINE_TEMPLATES_PATH", "").split(os.pathsep) - additionalPipelinesPath = [i for i in additionalPipelinesPath if i] - pipelineTemplatesFolders = [os.path.join(meshroomFolder, 'pipelines')] + additionalPipelinesPath + # Load pipeline templates: check in any folder the user might have added to the environment variable + pipelinesPath = os.environ.get("MESHROOM_PIPELINE_TEMPLATES_PATH", "").split(os.pathsep) + pipelineTemplatesFolders = [i for i in pipelinesPath if i] for f in pipelineTemplatesFolders: if os.path.isdir(f): loadPipelineTemplates(f) else: - logging.error("Pipeline templates folder '{}' does not exist.".format(f)) + logging.warning("Pipeline templates folder '{}' does not exist.".format(f)) From 752b63054d38cdb3803a9c9a12e3506d24a54c2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Candice=20Bent=C3=A9jac?= Date: Mon, 17 Mar 2025 16:49:42 +0100 Subject: [PATCH 5/9] [tests] Update `test_multiviewPipeline` with test nodes and template `test_multiviewPipeline` relied on the photogrammetry template and its nodes, which are not a part of Meshroom anymore. The test is rewritten to check the same items (serialization, graph equality, etc.) but using dedicated test nodes (which already existed) and template, which is added with this commit. The path of the template is added to `MESHROOM_PIPELINE_TEMPLATES_PATH` when loading the test module. --- tests/__init__.py | 6 +- tests/appendTextAndFiles.mg | 43 +++++++++++ tests/test_multiviewPipeline.py | 125 -------------------------------- tests/test_pipeline.py | 79 ++++++++++++++++++++ 4 files changed, 127 insertions(+), 126 deletions(-) create mode 100644 tests/appendTextAndFiles.mg delete mode 100644 tests/test_multiviewPipeline.py create mode 100644 tests/test_pipeline.py diff --git a/tests/__init__.py b/tests/__init__.py index 1760a89648..8a6bd273ca 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -1,5 +1,9 @@ import os -from meshroom.core import loadAllNodes +from meshroom.core import loadAllNodes, initPipelines loadAllNodes(os.path.join(os.path.dirname(__file__), "nodes")) +if os.getenv("MESHROOM_PIPELINE_TEMPLATES_PATH", False): + os.environ["MESHROOM_PIPELINE_TEMPLATES_PATH"] += os.pathsep + os.path.dirname(os.path.realpath(__file__)) +else: + os.environ["MESHROOM_PIPELINE_TEMPLATES_PATH"] = os.path.dirname(os.path.realpath(__file__)) diff --git a/tests/appendTextAndFiles.mg b/tests/appendTextAndFiles.mg new file mode 100644 index 0000000000..bbce48ebdc --- /dev/null +++ b/tests/appendTextAndFiles.mg @@ -0,0 +1,43 @@ +{ + "header": { + "releaseVersion": "2025.1.0-develop", + "fileVersion": "2.0", + "nodesVersions": {}, + "template": true + }, + "graph": { + "AppendFiles_1": { + "nodeType": "AppendFiles", + "position": [ + 189, + 8 + ], + "inputs": { + "input": "{AppendText_1.output}", + "input2": "{AppendText_2.output}", + "input3": "{AppendText_1.input}", + "input4": "{AppendText_2.input}" + } + }, + "AppendText_1": { + "nodeType": "AppendText", + "position": [ + 0, + 0 + ], + "inputs": { + "inputText": "Input text from AppendText_1" + } + }, + "AppendText_2": { + "nodeType": "AppendText", + "position": [ + 0, + 160 + ], + "inputs": { + "inputText": "Input text from AppendText_2" + } + } + } +} \ No newline at end of file diff --git a/tests/test_multiviewPipeline.py b/tests/test_multiviewPipeline.py deleted file mode 100644 index 0f10e57851..0000000000 --- a/tests/test_multiviewPipeline.py +++ /dev/null @@ -1,125 +0,0 @@ -#!/usr/bin/env python -# coding:utf-8 -import os -import tempfile - -import meshroom.multiview -from meshroom.core.graph import loadGraph -from meshroom.core.node import Node - - -def test_multiviewPipeline(): - meshroom.core.initNodes() - meshroom.core.initPipelines() - - graph1InputImages = ['/non/existing/fileA'] - graph1 = loadGraph(meshroom.core.pipelineTemplates["photogrammetry"]) - graph1.name = "graph1" - graph1CameraInit = graph1.node("CameraInit_1") - graph1CameraInit.viewpoints.extend([{'path': image} for image in graph1InputImages]) - - graph2InputImages = [] # common to graph2 and graph2b - graph2 = loadGraph(meshroom.core.pipelineTemplates["photogrammetry"]) - graph2.name = "graph2" - graph2CameraInit = graph2.node("CameraInit_1") - graph2CameraInit.viewpoints.extend([{'path': image} for image in graph2InputImages]) - graph2b = loadGraph(meshroom.core.pipelineTemplates["photogrammetry"]) - graph2bCameraInit = graph2b.node("CameraInit_1") - graph2bCameraInit.viewpoints.extend([{'path': image} for image in graph2InputImages]) - - graph3InputImages = ['/non/existing/file1', '/non/existing/file2'] - graph3 = loadGraph(meshroom.core.pipelineTemplates["photogrammetry"]) - graph3.name = "graph3" - graph3CameraInit = graph3.node("CameraInit_1") - graph3CameraInit.viewpoints.extend([{'path': image} for image in graph3InputImages]) - - graph4InputViewpoints = [ - {'path': '/non/existing/file1', 'intrinsicId': 50}, - {'path': '/non/existing/file2', 'intrinsicId': 55} - ] # common to graph4 and graph4b - graph4 = loadGraph(meshroom.core.pipelineTemplates["photogrammetry"]) - graph4.name = "graph4" - graph4CameraInit = graph4.node("CameraInit_1") - graph4CameraInit.viewpoints.extend(graph4InputViewpoints) - graph4b = loadGraph(meshroom.core.pipelineTemplates["photogrammetry"]) - graph4b.name = "graph4b" - graph4bCameraInit = graph4b.node("CameraInit_1") - graph4bCameraInit.viewpoints.extend(graph4InputViewpoints) - - assert graph1.findNode('CameraInit').viewpoints.at(0).path.value == '/non/existing/fileA' - assert len(graph2.findNode('CameraInit').viewpoints) == 0 - assert graph3.findNode('CameraInit').viewpoints.at(0).path.value == '/non/existing/file1' - assert graph4.findNode('CameraInit').viewpoints.at(0).path.value == '/non/existing/file1' - - assert len(graph1.findNode('CameraInit').viewpoints) == 1 - assert len(graph2.findNode('CameraInit').viewpoints) == 0 - assert len(graph3.findNode('CameraInit').viewpoints) == 2 - assert len(graph4.findNode('CameraInit').viewpoints) == 2 - - viewpoints = graph3.findNode('CameraInit').viewpoints - assert viewpoints.at(0).path.value == '/non/existing/file1' - - assert viewpoints.at(0).path.value == '/non/existing/file1' - assert viewpoints.at(0).intrinsicId.value == -1 - assert viewpoints.at(1).path.value == '/non/existing/file2' - assert viewpoints.at(1).intrinsicId.value == -1 - - assert not viewpoints.at(0).path.isDefault - assert viewpoints.at(0).intrinsicId.isDefault - assert viewpoints.getPrimitiveValue(exportDefault=False) == [ - {"path": '/non/existing/file1'}, - {"path": '/non/existing/file2'}, - ] - - for graph in (graph4, graph4b): - viewpoints = graph.findNode('CameraInit').viewpoints - assert viewpoints.at(0).path.value == '/non/existing/file1' - assert viewpoints.at(0).intrinsicId.value == 50 - assert viewpoints.at(1).path.value == '/non/existing/file2' - assert viewpoints.at(1).intrinsicId.value == 55 - - # Ensure that all output UIDs are different as the input is different: - # graph1 != graph2 != graph3 != graph4 - for otherGraph in (graph2, graph3, graph4): - for node in graph1.nodes: - otherNode = otherGraph.node(node.name) - for key, attr in node.attributes.items(): - if attr.isOutput and attr.enabled: - otherAttr = otherNode.attribute(key) - assert attr.uid() != otherAttr.uid() - - # graph2 == graph2b - nodes, edges = graph2.dfsOnFinish() - for node in nodes: - otherNode = graph2b.node(node.name) - for key, attr in node.attributes.items(): - otherAttr = otherNode.attribute(key) - if attr.isOutput and attr.enabled: - assert attr.uid() == otherAttr.uid() - else: - assert attr.uid() == otherAttr.uid() - - # graph4 == graph4b - nodes, edges = graph4.dfsOnFinish() - for node in nodes: - otherNode = graph4b.node(node.name) - for key, attr in node.attributes.items(): - otherAttr = otherNode.attribute(key) - if attr.isOutput and attr.enabled: - assert attr.uid() == otherAttr.uid() - else: - assert attr.uid() == otherAttr.uid() - - # test serialization/deserialization - for graph in [graph1, graph2, graph3, graph4]: - filename = tempfile.mktemp() - graph.save(filename) - loadedGraph = loadGraph(filename) - os.remove(filename) - # check that all nodes have been properly de-serialized - # - same node set - assert sorted([n.name for n in loadedGraph.nodes]) == sorted([n.name for n in graph.nodes]) - # - no compatibility issues - assert all(isinstance(n, Node) for n in loadedGraph.nodes) - # - same UIDs for every node - assert sorted([n._uid for n in loadedGraph.nodes]) == sorted([n._uid for n in graph.nodes]) diff --git a/tests/test_pipeline.py b/tests/test_pipeline.py new file mode 100644 index 0000000000..a536a04341 --- /dev/null +++ b/tests/test_pipeline.py @@ -0,0 +1,79 @@ +#!/usr/bin/env python +# coding:utf-8 +import os +import tempfile + +import meshroom.multiview +from meshroom.core.graph import loadGraph +from meshroom.core.node import Node + + +def test_pipeline(): + meshroom.core.initNodes() + meshroom.core.initPipelines() + + graph1InputFiles = ["/non/existing/file1", "/non/existing/file2"] + graph1 = loadGraph(meshroom.core.pipelineTemplates["appendTextAndFiles"]) + graph1.name = "graph1" + graph1AppendText1 = graph1.node("AppendText_1") + graph1AppendText1.input.value = graph1InputFiles[0] + graph1AppendText2 = graph1.node("AppendText_2") + graph1AppendText2.input.value = graph1InputFiles[1] + + assert graph1.findNode("AppendFiles").input.value == graph1AppendText1.output.value + assert graph1.findNode("AppendFiles").input2.value == graph1AppendText2.output.value + assert graph1.findNode("AppendFiles").input3.value == graph1InputFiles[0] + assert graph1.findNode("AppendFiles").input4.value == graph1InputFiles[1] + + assert not graph1AppendText1.input.isDefault + assert graph1AppendText2.input.getPrimitiveValue() == graph1InputFiles[1] + + graph2InputFiles = ["/non/existing/file", ""] + graph2 = loadGraph(meshroom.core.pipelineTemplates["appendTextAndFiles"]) + graph2.name = "graph2" + graph2AppendText1 = graph2.node("AppendText_1") + graph2AppendText1.input.value = graph2InputFiles[0] + graph2AppendText2 = graph2.node("AppendText_2") + graph2AppendText2.input.value = graph2InputFiles[1] + + # Ensure that all output UIDs are different as the input is different: + # graph1 != graph2 + for node in graph1.nodes: + otherNode = graph2.node(node.name) + for key, attr in node.attributes.items(): + if attr.isOutput and attr.enabled: + otherAttr = otherNode.attribute(key) + assert attr.uid() != otherAttr.uid() + + # Test serialization/deserialization on both graphs + for graph in [graph1, graph2]: + filename = tempfile.mktemp() + graph.save(filename) + loadedGraph = loadGraph(filename) + os.remove(filename) + # Check that all nodes have been properly de-serialized + # - Same node set + assert sorted([n.name for n in loadedGraph.nodes]) == sorted([n.name for n in graph.nodes]) + # - No compatibility issues + assert all(isinstance(n, Node) for n in loadedGraph.nodes) + # - Same UIDs for every node + assert sorted([n._uid for n in loadedGraph.nodes]) == sorted([n._uid for n in graph.nodes]) + + # Graph 2b, set with identical parameters as graph 2 + graph2b = loadGraph(meshroom.core.pipelineTemplates["appendTextAndFiles"]) + graph2b.name = "graph2b" + graph2bAppendText1 = graph2b.node("AppendText_1") + graph2bAppendText1.input.value = graph2InputFiles[0] + graph2bAppendText2 = graph2b.node("AppendText_2") + graph2bAppendText2.input.value = graph2InputFiles[1] + + # Ensure that graph2 == graph2b + nodes, edges = graph2.dfsOnFinish() + for node in nodes: + otherNode = graph2b.node(node.name) + for key, attr in node.attributes.items(): + otherAttr = otherNode.attribute(key) + if attr.isOutput and attr.enabled: + assert attr.uid() == otherAttr.uid() + else: + assert attr.uid() == otherAttr.uid() From 2fe7cfe95e7827a9a65dc921897d8a5f49dc7eb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Candice=20Bent=C3=A9jac?= Date: Mon, 17 Mar 2025 16:50:55 +0100 Subject: [PATCH 6/9] [tests] Remove `test_templatesVersion` This test checked that every node in all the available templates was free of any compatibility issue. As templates are not provided with Meshroom, it is not needed anymore. --- tests/test_templatesVersion.py | 61 ---------------------------------- 1 file changed, 61 deletions(-) delete mode 100644 tests/test_templatesVersion.py diff --git a/tests/test_templatesVersion.py b/tests/test_templatesVersion.py deleted file mode 100644 index eb23628f72..0000000000 --- a/tests/test_templatesVersion.py +++ /dev/null @@ -1,61 +0,0 @@ -#!/usr/bin/env python -# coding:utf-8 - -from meshroom.core.graph import Graph -from meshroom.core import pipelineTemplates, Version -from meshroom.core.node import CompatibilityIssue, CompatibilityNode -from meshroom.core.graphIO import GraphIO - -import json -import meshroom - - -def test_templateVersions(): - """ - This test checks that there is no compatibility issue with the nodes saved in the template files. - It fails when an upgrade of a templates is needed. Any template can still be opened even if its - nodes are not up-to-date, as they will be automatically upgraded. - """ - meshroom.core.initNodes() - meshroom.core.initPipelines() - - assert len(pipelineTemplates) >= 1 - - for _, path in pipelineTemplates.items(): - with open(path) as jsonFile: - fileData = json.load(jsonFile) - - graphData = fileData.get(GraphIO.Keys.Graph, fileData) - - assert isinstance(graphData, dict) - - header = fileData.get(GraphIO.Keys.Header, {}) - assert header.get("template", False) - nodesVersions = header.get(GraphIO.Keys.NodesVersions, {}) - - for _, nodeData in graphData.items(): - nodeType = nodeData["nodeType"] - assert nodeType in meshroom.core.nodesDesc - - nodeDesc = meshroom.core.nodesDesc[nodeType] - currentNodeVersion = meshroom.core.nodeVersion(nodeDesc) - - inputs = nodeData.get("inputs", {}) - internalInputs = nodeData.get("internalInputs", {}) - version = nodesVersions.get(nodeType, None) - - compatibilityIssue = None - - if version and currentNodeVersion and Version(version).major != Version(currentNodeVersion).major: - compatibilityIssue = CompatibilityIssue.VersionConflict - else: - for attrName, value in inputs.items(): - if not CompatibilityNode.attributeDescFromName(nodeDesc.inputs, attrName, value): - compatibilityIssue = CompatibilityIssue.DescriptionConflict - break - for attrName, value in internalInputs.items(): - if not CompatibilityNode.attributeDescFromName(nodeDesc.internalInputs, attrName, value): - compatibilityIssue = CompatibilityIssue.DescriptionConflict - break - - assert compatibilityIssue is None, "{} in {} for node {}".format(compatibilityIssue, path, nodeType) From cfa33b64428e5e3d930ca2a6b13f62d1daff5981 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Candice=20Bent=C3=A9jac?= Date: Mon, 17 Mar 2025 16:58:28 +0100 Subject: [PATCH 7/9] [core] Add a `test.py` file that contains sanity methods used for validation For now, it contains methods allowing to check whether a template provided as an argument is valid (i.e. has no compatibility issue). It performs a check that's very similar to what `test_templatesVersions` was doing, but it allows this check to be performed from outside of Meshroom. --- meshroom/core/test.py | 68 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 meshroom/core/test.py diff --git a/meshroom/core/test.py b/meshroom/core/test.py new file mode 100644 index 0000000000..74cb2f5cdc --- /dev/null +++ b/meshroom/core/test.py @@ -0,0 +1,68 @@ +#!/usr/bin/env python +# coding:utf-8 + +from meshroom.core import pipelineTemplates, Version +from meshroom.core.node import CompatibilityIssue, CompatibilityNode +from meshroom.core.graphIO import GraphIO + +import meshroom + +import json + +def checkTemplateVersions(path: str) -> bool: + """ Check whether there is a compatibility issue with the nodes saved in the template provided with "path". """ + meshroom.core.initNodes() + + with open(path) as jsonFile: + fileData = json.load(jsonFile) + + graphData = fileData.get(GraphIO.Keys.Graph, fileData) + if not isinstance(graphData, dict): + return False + + header = fileData.get(GraphIO.Keys.Header, {}) + if not header.get("template", False): + return False + nodesVersions = header.get(GraphIO.Keys.NodesVersions, {}) + + for _, nodeData in graphData.items(): + nodeType = nodeData["nodeType"] + if not nodeType in meshroom.core.nodesDesc: + return False + + nodeDesc = meshroom.core.nodesDesc[nodeType] + currentNodeVersion = meshroom.core.nodeVersion(nodeDesc) + + inputs = nodeData.get("inputs", {}) + internalInputs = nodeData.get("internalInputs", {}) + version = nodesVersions.get(nodeType, None) + + compatibilityIssue = None + + if version and currentNodeVersion and Version(version).major != Version(currentNodeVersion).major: + compatibilityIssue = CompatibilityIssue.VersionConflict + else: + for attrName, value in inputs.items(): + if not CompatibilityNode.attributeDescFromName(nodeDesc.inputs, attrName, value): + compatibilityIssue = CompatibilityIssue.DescriptionConflict + break + for attrName, value in internalInputs.items(): + if not CompatibilityNode.attributeDescFromName(nodeDesc.internalInputs, attrName, value): + compatibilityIssue = CompatibilityIssue.DescriptionConflict + break + + if compatibilityIssue is not None: + print("{} in {} for node {}".format(compatibilityIssue, path, nodeType)) + return False + + return True + + +def checkAllTemplatesVersions() -> bool: + meshroom.core.initPipelines() + + validVersions = [] + for _, path in pipelineTemplates.items(): + validVersions.append(checkTemplateVersions(path)) + + return all(validVersions) From ee5e9401ce27959ff7c345c7d4d339c78f615d6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Candice=20Bent=C3=A9jac?= Date: Mon, 17 Mar 2025 18:34:21 +0100 Subject: [PATCH 8/9] [tests] Rewrite `test_nodeCommandLineFormatting` using test nodes The tests in that file were using AliceVision nodes, which are now out of Meshroom's repository. --- tests/test_nodeCommandLineFormatting.py | 250 +++++++++++++++++------- 1 file changed, 174 insertions(+), 76 deletions(-) diff --git a/tests/test_nodeCommandLineFormatting.py b/tests/test_nodeCommandLineFormatting.py index 8c85c9c529..e7f2adf7a0 100644 --- a/tests/test_nodeCommandLineFormatting.py +++ b/tests/test_nodeCommandLineFormatting.py @@ -1,78 +1,176 @@ #!/usr/bin/env python # coding:utf-8 -import meshroom.multiview -from meshroom.core.graph import Graph - - -def test_formatting_listOfFiles(): - meshroom.core.initNodes() - - inputImages = ['/non/existing/fileA', '/non/existing/with space/fileB'] - - graph = Graph('') - n1 = graph.addNewNode('CameraInit') - n1.viewpoints.extend([{'path': image} for image in inputImages]) - # viewId, poseId, path, intrinsicId, rigId, subPoseId, metadata - assert n1.viewpoints.getValueStr() == \ - '-1 -1 "/non/existing/fileA" -1 -1 -1 "" -1 -1 "/non/existing/with space/fileB" -1 -1 -1 ""' - - graph = Graph('') - n1 = graph.addNewNode('ImageMatching') - assert n1.featuresFolders.getValueStr() == '' - - n1.featuresFolders.extend("single value with space") - assert n1.featuresFolders.getValueStr() == '"single value with space"' - - n1.featuresFolders.resetToDefaultValue() - assert n1.featuresFolders.getValueStr() == '' - - n1.featuresFolders.extend(inputImages) - assert n1.featuresFolders.getValueStr() == '"/non/existing/fileA" "/non/existing/with space/fileB"' - - n1._buildCmdVars() # prepare vars for command line creation - # and check some values - name = 'featuresFolders' - assert n1._cmdVars[name + 'Value'] == '/non/existing/fileA /non/existing/with space/fileB' - - -def test_formatting_strings(): - meshroom.core.initNodes() - - graph = Graph('') - n1 = graph.addNewNode('ImageMatching') - name = 'weights' - assert n1.weights.getValueStr() == '""' # Empty string should generate empty quotes - assert n1._cmdVars[name + 'Value'] == '' - name = 'method' - assert n1.method.getValueStr() == '"SequentialAndVocabularyTree"' - assert n1._cmdVars[name + 'Value'] == 'SequentialAndVocabularyTree' - - n2 = graph.addNewNode('ImageMatching') - n2._buildCmdVars() # prepare vars for command line creation - name = 'featuresFolders' - assert n2._cmdVars[name + 'Value'] == '', 'Empty list should become fully empty' - n2.featuresFolders.extend('') - n2._buildCmdVars() # prepare vars for command line creation - assert n2.featuresFolders.getValueStr() == '""', 'A list with one empty string should generate empty quotes' - assert n2._cmdVars[name + 'Value'] == '', 'The Value is always only the value, so empty here' - n2.featuresFolders.extend('') - n2._buildCmdVars() # prepare vars for command line creation - assert n2.featuresFolders.getValueStr() == '"" ""', 'A list with 2 empty strings should generate quotes' - assert n2._cmdVars[name + 'Value'] == ' ', \ - 'The Value is always only the value, so 2 empty with the space separator in the middle' - - -def test_formatting_groups(): - meshroom.core.initNodes() - - graph = Graph('') - n3 = graph.addNewNode('ImageProcessing') - n3._buildCmdVars() # prepare vars for command line creation - name = 'sharpenFilter' - assert n3.sharpenFilter.getValueStr() == '"False:3:1.0:0.0"' - assert n3._cmdVars[name + 'Value'] == 'False:3:1.0:0.0', 'The Value is always only the value, so no quotes' - name = 'fillHoles' - assert n3._cmdVars[name + 'Value'] == 'False', 'Booleans' - name = 'noiseFilter' - assert n3.noiseFilter.getValueStr() == '"False:uniform:0.0:1.0:True"' - assert n3._cmdVars[name + 'Value'] == 'False:uniform:0.0:1.0:True' + +from meshroom.core.graph import Graph, loadGraph, executeGraph +from meshroom.core import desc, registerNodeType, unregisterNodeType +from meshroom.core.node import Node + + +class NodeWithAttributesNeedingFormatting(desc.Node): + """ + A node containing list, file, choice and group attributes in order to test the formatting of the command line. + """ + inputs = [ + desc.ListAttribute( + name="images", + label="Images", + description="List of images.", + elementDesc=desc.File( + name="image", + label="Image", + description="Path to an image.", + value="", + ), + ), + desc.File( + name="input", + label="Input File", + description="An input file.", + value="", + ), + desc.ChoiceParam( + name="method", + label="Method", + description="Method to choose from a list of available methods.", + value="MethodC", + values=["MethodA", "MethodB", "MethodC"], + ), + desc.GroupAttribute( + name="firstGroup", + label="First Group", + description="Group with boolean and integer parameters.", + joinChar=":", + groupDesc=[ + desc.BoolParam( + name="enableFirstGroup", + label="Enable", + description="Enable other parameter in the group.", + value=False, + ), + desc.IntParam( + name="width", + label="Width", + description="Width setting.", + value=3, + range=(1, 10, 1), + enabled=lambda node: node.firstGroup.enableFirstGroup.value, + ), + ] + ), + desc.GroupAttribute( + name="secondGroup", + label="Second Group", + description="Group with boolean, choice and float parameters.", + joinChar=",", + groupDesc=[ + desc.BoolParam( + name="enableSecondGroup", + label="Enable", + description="Enable other parameters in the group.", + value=False, + ), + desc.ChoiceParam( + name="groupChoice", + label="Grouped Choice", + description="Value to choose from a group.", + value="second_value", + values=["first_value", "second_value", "third_value"], + enabled=lambda node: node.secondGroup.enableSecondGroup.value, + ), + desc.FloatParam( + name="floatWidth", + label="Width", + description="Width setting (but with a float).", + value=3.0, + range=(1.0, 10.0, 0.5), + enabled=lambda node: node.secondGroup.enableSecondGroup.value, + ), + ], + ), + ] + + outputs = [ + desc.File( + name="output", + label="Output", + description="Output file.", + value="{nodeCacheFolder}", + ), + ] + +class TestCommandLineFormatting: + @classmethod + def setup_class(cls): + registerNodeType(NodeWithAttributesNeedingFormatting) + + @classmethod + def teardown_class(cls): + unregisterNodeType(NodeWithAttributesNeedingFormatting) + + def test_formatting_listOfFiles(self): + inputImages = ["/non/existing/fileA", "/non/existing/with space/fileB"] + + graph = Graph("") + node = graph.addNewNode("NodeWithAttributesNeedingFormatting") + + # Assert that an empty list gives an empty string + assert node.images.getValueStr() == "" + + # Assert that values in a list a correctly concatenated + node.images.extend([i for i in inputImages]) + assert node.images.getValueStr() == '"/non/existing/fileA" "/non/existing/with space/fileB"' + + # Reset list content and add a single value that contains spaces + node.images.resetToDefaultValue() + assert node.images.getValueStr() == "" # The value has been correctly reset + node.images.extend("single value with space") + assert node.images.getValueStr() == '"single value with space"' + + # Assert that extending values when the list is not empty is working + node.images.extend(inputImages) + assert node.images.getValueStr() == '"single value with space" "{}" "{}"'.format(inputImages[0], + inputImages[1]) + + # Values are not retrieved as strings in the command line, so quotes around them are not expected + assert node._cmdVars["imagesValue"] == 'single value with space {} {}'.format(inputImages[0], + inputImages[1]) + + def test_formatting_strings(self): + graph = Graph("") + node = graph.addNewNode("NodeWithAttributesNeedingFormatting") + node._buildCmdVars() + + # Assert an empty File attribute generates empty quotes when requesting its value as a string + assert node.input.getValueStr() == '""' + assert node._cmdVars["inputValue"] == "" + + # Assert a Choice attribute with a non-empty default value is surrounded with quotes when requested as a string + assert node.method.getValueStr() == '"MethodC"' + assert node._cmdVars["methodValue"] == "MethodC" + + # Assert that the empty list is really empty (no quotes) + assert node.images.getValueStr() == "" + assert node._cmdVars["imagesValue"] == "", "Empty list should become fully empty" + + # Assert that the list with one empty value generates empty quotes + node.images.extend("") + assert node.images.getValueStr() == '""', "A list with one empty string should generate empty quotes" + assert node._cmdVars["imagesValue"] == "", "The value is always only the value, so empty here" + + # Assert that a list with 2 empty strings generates quotes + node.images.extend("") + assert node.images.getValueStr() == '"" ""', "A list with 2 empty strings should generate quotes" + assert node._cmdVars["imagesValue"] == ' ', \ + "The value is always only the value, so 2 empty strings with the space separator in the middle" + + def test_formatting_groups(self): + graph = Graph("") + node = graph.addNewNode("NodeWithAttributesNeedingFormatting") + node._buildCmdVars() + + assert node.firstGroup.getValueStr() == '"False:3"' + assert node._cmdVars["firstGroupValue"] == 'False:3', \ + "There should be no quotes here as the value is not formatted as a string" + + assert node.secondGroup.getValueStr() == '"False,second_value,3.0"' + assert node._cmdVars["secondGroupValue"] == 'False,second_value,3.0' From c3e8b8833f401bf1d6e2e4274cf34f675efe847d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Candice=20Bent=C3=A9jac?= Date: Tue, 18 Mar 2025 14:04:06 +0000 Subject: [PATCH 9/9] [core] `checkTemplateVersions`: Ensure nodes are not loaded several times By performing a `initNodes()` every single time `checkTemplateVersions` was called without ever unregistering the nodes, warnings about nodes being already registered were raised when for example calling `checkAllTemplatesVersions`. --- meshroom/core/test.py | 89 ++++++++++++++++++++++++------------------- 1 file changed, 49 insertions(+), 40 deletions(-) diff --git a/meshroom/core/test.py b/meshroom/core/test.py index 74cb2f5cdc..85e7a021b7 100644 --- a/meshroom/core/test.py +++ b/meshroom/core/test.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # coding:utf-8 -from meshroom.core import pipelineTemplates, Version +from meshroom.core import unregisterNodeType, pipelineTemplates, Version from meshroom.core.node import CompatibilityIssue, CompatibilityNode from meshroom.core.graphIO import GraphIO @@ -9,60 +9,69 @@ import json -def checkTemplateVersions(path: str) -> bool: +def checkTemplateVersions(path: str, nodesAlreadyLoaded: bool = False) -> bool: """ Check whether there is a compatibility issue with the nodes saved in the template provided with "path". """ - meshroom.core.initNodes() + if not nodesAlreadyLoaded: + meshroom.core.initNodes() with open(path) as jsonFile: fileData = json.load(jsonFile) - graphData = fileData.get(GraphIO.Keys.Graph, fileData) - if not isinstance(graphData, dict): - return False - - header = fileData.get(GraphIO.Keys.Header, {}) - if not header.get("template", False): - return False - nodesVersions = header.get(GraphIO.Keys.NodesVersions, {}) - - for _, nodeData in graphData.items(): - nodeType = nodeData["nodeType"] - if not nodeType in meshroom.core.nodesDesc: + try: + graphData = fileData.get(GraphIO.Keys.Graph, fileData) + if not isinstance(graphData, dict): return False - nodeDesc = meshroom.core.nodesDesc[nodeType] - currentNodeVersion = meshroom.core.nodeVersion(nodeDesc) - - inputs = nodeData.get("inputs", {}) - internalInputs = nodeData.get("internalInputs", {}) - version = nodesVersions.get(nodeType, None) - - compatibilityIssue = None - - if version and currentNodeVersion and Version(version).major != Version(currentNodeVersion).major: - compatibilityIssue = CompatibilityIssue.VersionConflict - else: - for attrName, value in inputs.items(): - if not CompatibilityNode.attributeDescFromName(nodeDesc.inputs, attrName, value): - compatibilityIssue = CompatibilityIssue.DescriptionConflict - break - for attrName, value in internalInputs.items(): - if not CompatibilityNode.attributeDescFromName(nodeDesc.internalInputs, attrName, value): - compatibilityIssue = CompatibilityIssue.DescriptionConflict - break - - if compatibilityIssue is not None: - print("{} in {} for node {}".format(compatibilityIssue, path, nodeType)) + header = fileData.get(GraphIO.Keys.Header, {}) + if not header.get("template", False): return False + nodesVersions = header.get(GraphIO.Keys.NodesVersions, {}) + + for _, nodeData in graphData.items(): + nodeType = nodeData["nodeType"] + if not nodeType in meshroom.core.nodesDesc: + return False + + nodeDesc = meshroom.core.nodesDesc[nodeType] + currentNodeVersion = meshroom.core.nodeVersion(nodeDesc) + + inputs = nodeData.get("inputs", {}) + internalInputs = nodeData.get("internalInputs", {}) + version = nodesVersions.get(nodeType, None) - return True + compatibilityIssue = None + + if version and currentNodeVersion and Version(version).major != Version(currentNodeVersion).major: + compatibilityIssue = CompatibilityIssue.VersionConflict + else: + for attrName, value in inputs.items(): + if not CompatibilityNode.attributeDescFromName(nodeDesc.inputs, attrName, value): + compatibilityIssue = CompatibilityIssue.DescriptionConflict + break + for attrName, value in internalInputs.items(): + if not CompatibilityNode.attributeDescFromName(nodeDesc.internalInputs, attrName, value): + compatibilityIssue = CompatibilityIssue.DescriptionConflict + break + + if compatibilityIssue is not None: + print("{} in {} for node {}".format(compatibilityIssue, path, nodeType)) + return False + + return True + + finally: + if not nodesAlreadyLoaded: + nodeTypes = [nodeType for _, nodeType in meshroom.core.nodesDesc.items()] + for nodeType in nodeTypes: + unregisterNodeType(nodeType) def checkAllTemplatesVersions() -> bool: + meshroom.core.initNodes() meshroom.core.initPipelines() validVersions = [] for _, path in pipelineTemplates.items(): - validVersions.append(checkTemplateVersions(path)) + validVersions.append(checkTemplateVersions(path, nodesAlreadyLoaded=True)) return all(validVersions)