示例#1
0
class FeatureExtraction(desc.CommandLineNode):
    commandLine = 'aliceVision_featureExtraction {allParams}'
    size = desc.DynamicNodeSize('input')
    parallelization = desc.Parallelization(blockSize=40)
    commandLineRange = '--rangeStart {rangeStart} --rangeSize {rangeBlockSize}'

    inputs = [
        desc.File(
            name='input',
            label='Input',
            description='SfMData file.',
            value='',
            uid=[0],
        ),
        desc.ChoiceParam(
            name='describerTypes',
            label='Describer Types',
            description='Describer types used to describe an image.',
            value=['sift'],
            values=['sift', 'sift_float', 'sift_upright', 'akaze', 'akaze_liop', 'akaze_mldb', 'cctag3', 'cctag4', 'sift_ocv', 'akaze_ocv'],
            exclusive=False,
            uid=[0],
            joinChar=',',
        ),
        desc.ChoiceParam(
            name='describerPreset',
            label='Describer Preset',
            description='Control the ImageDescriber configuration (low, medium, normal, high, ultra). Configuration "ultra" can take long time !',
            value='normal',
            values=['low', 'medium', 'normal', 'high', 'ultra'],
            exclusive=True,
            uid=[0],
        ),
        desc.BoolParam(
            name='forceCpuExtraction',
            label='Force CPU Extraction',
            description='Use only CPU feature extraction.',
            value=True,
            uid=[],
        ),
        desc.ChoiceParam(
            name='verboseLevel',
            label='Verbose Level',
            description='verbosity level (fatal, error, warning, info, debug, trace).',
            value='info',
            values=['fatal', 'error', 'warning', 'info', 'debug', 'trace'],
            exclusive=True,
            uid=[],
        )
    ]

    outputs = [
        desc.File(
            name='output',
            label='Output Folder',
            description='Output path for the features and descriptors files (*.feat, *.desc).',
            value=desc.Node.internalFolder,
            uid=[],
        ),
    ]
class PrepareDenseScene(desc.CommandLineNode):
    commandLine = 'aliceVision_prepareDenseScene {allParams}'
    size = desc.DynamicNodeSize('input')
    parallelization = desc.Parallelization(blockSize=40)
    commandLineRange = '--rangeStart {rangeStart} --rangeSize {rangeBlockSize}'

    inputs = [
        desc.File(
            name='input',
            label='Input',
            description='''SfMData file.''',
            value='',
            uid=[0],
        ),
        desc.ChoiceParam(
            name='outputFileType',
            label='Output File Type',
            description='Output file type for the undistorted images.',
            value='exr',
            values=['jpg', 'png', 'tif', 'exr'],
            exclusive=True,
            uid=[0],
        ),
        desc.BoolParam(
            name='saveMetadata',
            label='Save Metadata',
            description='Save projections and intrinsics informations in images metadata (only for .exr images).',
            value=True,
            uid=[0],
        ),
        desc.BoolParam(
            name='saveMatricesTxtFiles',
            label='Save Matrices Text Files',
            description='Save projections and intrinsics informations in text files.',
            value=False,
            uid=[0],
        ),
        desc.ChoiceParam(
            name='verboseLevel',
            label='Verbose Level',
            description='''verbosity level (fatal, error, warning, info, debug, trace).''',
            value='info',
            values=['fatal', 'error', 'warning', 'info', 'debug', 'trace'],
            exclusive=True,
            uid=[],
        ),
    ]

    outputs = [
        desc.File(
            name='output',
            label='Output',
            description='''Output folder.''',
            value=desc.Node.internalFolder,
            uid=[],
        )
    ]
示例#3
0
class Publish(desc.Node):
    size = desc.DynamicNodeSize('inputFiles')
    inputs = [
        desc.ListAttribute(
            elementDesc=desc.File(
                name="input",
                label="Input",
                description="",
                value="",
                uid=[0],
            ),
            name="inputFiles",
            label="Input Files",
            description="Input Files to publish.",
            group="",
        ),
        desc.File(
            name="output",
            label="Output Folder",
            description="",
            value="",
            uid=[0],
        ),
    ]

    def resolvedPaths(self, inputFiles, outDir):
        paths = {}
        for inputFile in inputFiles:
            for f in glob.glob(inputFile.value):
                paths[f] = os.path.join(outDir, os.path.basename(f))
        return paths

    def processChunk(self, chunk):
        print("Publish")
        if not chunk.node.inputFiles:
            print("Nothing to publish")
            return
        if not chunk.node.output.value:
            return

        outFiles = self.resolvedPaths(chunk.node.inputFiles.value,
                                      chunk.node.output.value)

        if not outFiles:
            raise RuntimeError(
                "Publish: input files listed, but nothing to publish. "
                "Listed input files: {}".format(chunk.node.inputFiles.value))

        if not os.path.exists(chunk.node.output.value):
            os.mkdir(chunk.node.output.value)

        for iFile, oFile in outFiles.items():
            print('Publish file', iFile, 'into', oFile)
            shutil.copyfile(iFile, oFile)
        print('Publish end')
示例#4
0
class PanoramaExternalInfo(desc.CommandLineNode):
    commandLine = 'aliceVision_panoramaExternalInfo {allParams}'
    size = desc.DynamicNodeSize('input')

    inputs = [
        desc.File(
            name='input',
            label='Input',
            description="SfM Data File",
            value='',
            uid=[0],
        ),
        desc.File(
            name='config',
            label='Xml Config',
            description="XML Data File",
            value='',
            uid=[0],
        ),
        desc.ListAttribute(
            elementDesc=desc.File(
                name='matchesFolder',
                label='Matches Folder',
                description="",
                value='',
                uid=[0],
            ),
            name='matchesFolders',
            label='Matches Folders',
            description=
            "Folder(s) in which computed matches are stored. (WORKAROUND for valid Tractor graph submission)",
            group='forDependencyOnly',
        ),
        desc.ChoiceParam(
            name='verboseLevel',
            label='Verbose Level',
            description=
            'Verbosity level (fatal, error, warning, info, debug, trace).',
            value='info',
            values=['fatal', 'error', 'warning', 'info', 'debug', 'trace'],
            exclusive=True,
            uid=[],
        ),
    ]

    outputs = [
        desc.File(
            name='outSfMDataFilename',
            label='Output SfMData File',
            description='Path to the output sfmdata file',
            value=desc.Node.internalFolder + 'sfmData.abc',
            uid=[],
        )
    ]
示例#5
0
class PanoramaCompositing(desc.CommandLineNode):
    commandLine = 'aliceVision_panoramaCompositing {allParams}'
    size = desc.DynamicNodeSize('input')

    inputs = [
        desc.File(
            name='input',
            label='Input',
            description="Panorama Warping result",
            value='',
            uid=[0],
        ),
        desc.ChoiceParam(
            name='outputFileType',
            label='Output File Type',
            description='Output file type for the undistorted images.',
            value='exr',
            values=['jpg', 'png', 'tif', 'exr'],
            exclusive=True,
            uid=[0],
            group=
            '',  # not part of allParams, as this is not a parameter for the command line
        ),
        desc.ChoiceParam(
            name='compositerType',
            label='Compositer Type',
            description='Which compositer should be used to blend images',
            value='multiband',
            values=['replace', 'alpha', 'multiband'],
            exclusive=True,
            uid=[0]),
        desc.ChoiceParam(
            name='verboseLevel',
            label='Verbose Level',
            description=
            'Verbosity level (fatal, error, warning, info, debug, trace).',
            value='info',
            values=['fatal', 'error', 'warning', 'info', 'debug', 'trace'],
            exclusive=True,
            uid=[],
        ),
    ]

    outputs = [
        desc.File(
            name='output',
            label='Output Panorama',
            description='',
            value=desc.Node.internalFolder + 'panorama.{outputFileTypeValue}',
            uid=[],
        ),
    ]
示例#6
0
class CameraDownscale(desc.CommandLineNode):
    commandLine = 'aliceVision_cameraDownscale {allParams}'
    size = desc.DynamicNodeSize('input')

    inputs = [
        desc.File(
            name='input',
            label='Input',
            description="SfM Data File",
            value='',
            uid=[0],
        ),
        desc.FloatParam(
            name='rescalefactor',
            label='RescaleFactor',
            description='Newsize = rescalefactor * oldsize',
            value=0.5,
            range=(0.0, 1.0, 0.1),
            uid=[0],
            advanced=True,
        ),
        desc.ChoiceParam(
            name='verboseLevel',
            label='Verbose Level',
            description=
            'Verbosity level (fatal, error, warning, info, debug, trace).',
            value='info',
            values=['fatal', 'error', 'warning', 'info', 'debug', 'trace'],
            exclusive=True,
            uid=[],
        ),
    ]

    outputs = [
        desc.File(
            name='outSfMDataFilename',
            label='Output SfMData File',
            description='Path to the output sfmdata file',
            value=desc.Node.internalFolder + 'sfmData.abc',
            uid=[],
        )
    ]
示例#7
0
class PrepareDenseScene(desc.CommandLineNode):
    commandLine = 'aliceVision_prepareDenseScene {allParams}'
    size = desc.DynamicNodeSize('input')

    inputs = [
        desc.File(
            name='input',
            label='Input',
            description='''SfMData file.''',
            value='',
            uid=[0],
        ),
        desc.ChoiceParam(
            name='verboseLevel',
            label='Verbose Level',
            description=
            '''verbosity level (fatal, error, warning, info, debug, trace).''',
            value='info',
            values=['fatal', 'error', 'warning', 'info', 'debug', 'trace'],
            exclusive=True,
            uid=[],
        ),
    ]

    outputs = [
        desc.File(
            name='ini',
            label='MVS Configuration file',
            description='',
            value=desc.Node.internalFolder + 'mvs.ini',
            uid=[],
            group='',  # not a command line arg
        ),
        desc.File(
            name='output',
            label='Output',
            description='''Output folder.''',
            value=desc.Node.internalFolder,
            uid=[],
        )
    ]
示例#8
0
class SfMAlignment(desc.CommandLineNode):
    commandLine = 'aliceVision_utils_sfmAlignment {allParams}'
    size = desc.DynamicNodeSize('input')

    inputs = [
        desc.File(
            name='input',
            label='Input',
            description='''SfMData file .''',
            value='',
            uid=[0],
        ),
        desc.File(
            name='reference',
            label='Reference',
            description=
            '''Path to the scene used as the reference coordinate system.''',
            value='',
            uid=[0],
        ),
        desc.ChoiceParam(
            name='verboseLevel',
            label='Verbose Level',
            description=
            '''verbosity level (fatal, error, warning, info, debug, trace).''',
            value='info',
            values=['fatal', 'error', 'warning', 'info', 'debug', 'trace'],
            exclusive=True,
            uid=[],
        ),
    ]

    outputs = [
        desc.File(
            name='output',
            label='Output',
            description='''Aligned SfMData file .''',
            value=desc.Node.internalFolder + 'alignedSfM.abc',
            uid=[],
        ),
    ]
示例#9
0
class PanoramaWarping(desc.CommandLineNode):
    commandLine = 'aliceVision_panoramaWarping {allParams}'
    size = desc.DynamicNodeSize('input')

    inputs = [
        desc.File(
            name='input',
            label='Input',
            description="SfM Data File",
            value='',
            uid=[0],
        ),
        desc.IntParam(
            name='panoramaWidth',
            label='Panorama Width',
            description='Panorama width (pixels). 0 For automatic size',
            value=10000,
            range=(0, 50000, 1000),
            uid=[0]),
        desc.ChoiceParam(
            name='verboseLevel',
            label='Verbose Level',
            description=
            'Verbosity level (fatal, error, warning, info, debug, trace).',
            value='info',
            values=['fatal', 'error', 'warning', 'info', 'debug', 'trace'],
            exclusive=True,
            uid=[],
        ),
    ]

    outputs = [
        desc.File(
            name='output',
            label='Output directory',
            description='',
            value=desc.Node.internalFolder,
            uid=[],
        ),
    ]
示例#10
0
class PanoramaPrepareImages(desc.CommandLineNode):
    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='',
            uid=[0],
        ),
        desc.ChoiceParam(
            name='verboseLevel',
            label='Verbose Level',
            description=
            'verbosity level (fatal, error, warning, info, debug, trace).',
            value='info',
            values=['fatal', 'error', 'warning', 'info', 'debug', 'trace'],
            exclusive=True,
            uid=[],
        )
    ]

    outputs = [
        desc.File(
            name='output',
            label='Output sfmData',
            description='Output sfmData.',
            value=lambda attr: desc.Node.internalFolder + os.path.basename(
                attr.node.input.value),
            uid=[],
        ),
    ]
示例#11
0
class CameraConnection(desc.CommandLineNode):
    internalFolder = desc.Node.internalFolder
    commandLine = 'aliceVision_cameraConnection {allParams}'
    size = desc.DynamicNodeSize('ini')

    inputs = [
        desc.File(
            name="ini",
            label='MVS Configuration file',
            description='',
            value='',
            uid=[0],
        ),
        desc.ChoiceParam(
            name='verboseLevel',
            label='Verbose Level',
            description=
            '''verbosity level (fatal, error, warning, info, debug, trace).''',
            value='info',
            values=['fatal', 'error', 'warning', 'info', 'debug', 'trace'],
            exclusive=True,
            uid=[],
        ),
    ]
示例#12
0
class DepthMap(desc.CommandLineNode):
    commandLine = 'aliceVision_depthMapEstimation {allParams}'
    gpu = desc.Level.INTENSIVE
    size = desc.DynamicNodeSize('input')
    parallelization = desc.Parallelization(blockSize=3)
    commandLineRange = '--rangeStart {rangeStart} --rangeSize {rangeBlockSize}'

    category = 'Dense Reconstruction'
    documentation = '''
For each camera that have been estimated by the Structure-From-Motion, it estimates the depth value per pixel.

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='SfMData file.',
            value='',
            uid=[0],
        ),
        desc.File(
            name='imagesFolder',
            label='Images Folder',
            description=
            'Use images from a specific folder instead of those specify in the SfMData file.\nFilename should be the image uid.',
            value='',
            uid=[0],
        ),
        desc.ChoiceParam(
            name='downscale',
            label='Downscale',
            description='Image downscale factor.',
            value=2,
            values=[1, 2, 4, 8, 16],
            exclusive=True,
            uid=[0],
        ),
        desc.FloatParam(
            name='minViewAngle',
            label='Min View Angle',
            description='Minimum angle between two views.',
            value=2.0,
            range=(0.0, 10.0, 0.1),
            uid=[0],
            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),
            uid=[0],
            advanced=True,
        ),
        desc.IntParam(
            name='sgmMaxTCams',
            label='SGM: Nb Neighbour Cameras',
            description='Semi Global Matching: Number of neighbour cameras.',
            value=10,
            range=(1, 100, 1),
            uid=[0],
        ),
        desc.IntParam(
            name='sgmWSH',
            label='SGM: WSH',
            description=
            'Semi Global Matching: Half-size of the patch used to compute the similarity.',
            value=4,
            range=(1, 20, 1),
            uid=[0],
            advanced=True,
        ),
        desc.FloatParam(
            name='sgmGammaC',
            label='SGM: GammaC',
            description='Semi Global Matching: GammaC Threshold.',
            value=5.5,
            range=(0.0, 30.0, 0.5),
            uid=[0],
            advanced=True,
        ),
        desc.FloatParam(
            name='sgmGammaP',
            label='SGM: GammaP',
            description='Semi Global Matching: GammaP Threshold.',
            value=8.0,
            range=(0.0, 30.0, 0.5),
            uid=[0],
            advanced=True,
        ),
        desc.IntParam(
            name='refineMaxTCams',
            label='Refine: Nb Neighbour Cameras',
            description='Refine: Number of neighbour cameras.',
            value=6,
            range=(1, 20, 1),
            uid=[0],
        ),
        desc.IntParam(
            name='refineNSamplesHalf',
            label='Refine: Number of Samples',
            description='Refine: Number of samples.',
            value=150,
            range=(1, 500, 10),
            uid=[0],
            advanced=True,
        ),
        desc.IntParam(
            name='refineNDepthsToRefine',
            label='Refine: Number of Depths',
            description='Refine: Number of depths.',
            value=31,
            range=(1, 100, 1),
            uid=[0],
            advanced=True,
        ),
        desc.IntParam(
            name='refineNiters',
            label='Refine: Number of Iterations',
            description='Refine:: Number of iterations.',
            value=100,
            range=(1, 500, 10),
            uid=[0],
            advanced=True,
        ),
        desc.IntParam(
            name='refineWSH',
            label='Refine: WSH',
            description=
            'Refine: Half-size of the patch used to compute the similarity.',
            value=3,
            range=(1, 20, 1),
            uid=[0],
            advanced=True,
        ),
        desc.FloatParam(
            name='refineSigma',
            label='Refine: Sigma',
            description='Refine: Sigma Threshold.',
            value=15,
            range=(0.0, 30.0, 0.5),
            uid=[0],
            advanced=True,
        ),
        desc.FloatParam(
            name='refineGammaC',
            label='Refine: GammaC',
            description='Refine: GammaC Threshold.',
            value=15.5,
            range=(0.0, 30.0, 0.5),
            uid=[0],
            advanced=True,
        ),
        desc.FloatParam(
            name='refineGammaP',
            label='Refine: GammaP',
            description='Refine: GammaP threshold.',
            value=8.0,
            range=(0.0, 30.0, 0.5),
            uid=[0],
            advanced=True,
        ),
        desc.BoolParam(
            name='refineUseTcOrRcPixSize',
            label='Refine: Tc or Rc pixel size',
            description=
            'Refine: Use minimum pixel size of neighbour cameras (Tc) or current camera pixel size (Rc)',
            value=False,
            uid=[0],
            advanced=True,
        ),
        desc.BoolParam(
            name='exportIntermediateResults',
            label='Export Intermediate Results',
            description=
            'Export intermediate results from the SGM and Refine steps.',
            value=False,
            uid=[],
            advanced=True,
        ),
        desc.IntParam(
            name='nbGPUs',
            label='Number of GPUs',
            description=
            'Number of GPUs to use (0 means use all available GPUs).',
            value=0,
            range=(0, 5, 1),
            uid=[],
            advanced=True,
        ),
        desc.ChoiceParam(
            name='verboseLevel',
            label='Verbose Level',
            description=
            '''verbosity level (fatal, error, warning, info, debug, trace).''',
            value='info',
            values=['fatal', 'error', 'warning', 'info', 'debug', 'trace'],
            exclusive=True,
            uid=[],
        ),
    ]

    outputs = [
        desc.File(
            name='output',
            label='Output',
            description='Output folder for generated depth maps.',
            value=desc.Node.internalFolder,
            uid=[],
        ),
    ]
示例#13
0
class ImageProcessing(desc.CommandLineNode):
    commandLine = 'aliceVision_utils_imageProcessing {allParams}'
    size = desc.DynamicNodeSize('input')
    # parallelization = desc.Parallelization(blockSize=40)
    # commandLineRange = '--rangeStart {rangeStart} --rangeSize {rangeBlockSize}'

    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.\nsupported regex: \'#\' matches a single digit, \'@\' one or more digits, \'?\' one character and \'*\' zero or more.',
            value='',
            uid=[0],
        ),
        desc.ListAttribute(
            elementDesc=desc.File(
                name="inputFolder",
                label="input Folder",
                description="",
                value="",
                uid=[0],
            ),
            name="inputFolders",
            label="Images input Folders",
            description='Use images from specific folder(s).',
        ),
        desc.ListAttribute(
            elementDesc=desc.StringParam(
                name="metadataFolder",
                label="Metadata Folder",
                description="",
                value="",
                uid=[0],
            ),
            name="metadataFolders",
            label="Metadata input Folders",
            description='Use images metadata from specific folder(s).',
        ),
        desc.ChoiceParam(
            name='extension',
            label='Output File Extension',
            description='Output Image File Extension.',
            value='',
            values=['', 'exr', 'jpg', 'tiff', 'png'],
            exclusive=True,
            uid=[0],
        ),
        desc.BoolParam(
            name='reconstructedViewsOnly',
            label='Only Reconstructed Views',
            description='Process Only Reconstructed Views',
            value=False,
            uid=[0],
        ),
        desc.BoolParam(
            name='fixNonFinite',
            label='Fix Non-Finite',
            description=
            'Fix non-finite pixels based on neighboring pixels average.',
            value=False,
            uid=[0],
        ),
        desc.BoolParam(
            name='exposureCompensation',
            label='Exposure Compensation',
            description='Exposure Compensation',
            value=False,
            uid=[0],
        ),
        desc.FloatParam(
            name='scaleFactor',
            label='ScaleFactor',
            description='Scale Factor.',
            value=1.0,
            range=(0.0, 1.0, 0.01),
            uid=[0],
        ),
        desc.FloatParam(
            name='contrast',
            label='Contrast',
            description='Contrast.',
            value=1.0,
            range=(0.0, 100.0, 0.1),
            uid=[0],
        ),
        desc.IntParam(
            name='medianFilter',
            label='Median Filter',
            description='Median Filter.',
            value=0,
            range=(0, 10, 1),
            uid=[0],
        ),
        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,
            uid=[0],
        ),
        desc.GroupAttribute(name="sharpenFilter",
                            label="Sharpen Filter",
                            description="Sharpen Filtering Parameters.",
                            joinChar=":",
                            groupDesc=[
                                desc.BoolParam(
                                    name='sharpenFilterEnabled',
                                    label='Enable',
                                    description='Use sharpen.',
                                    value=False,
                                    uid=[0],
                                ),
                                desc.IntParam(
                                    name='width',
                                    label='Width',
                                    description='Sharpen Width.',
                                    value=3,
                                    range=(1, 9, 2),
                                    uid=[0],
                                    enabled=lambda node: node.sharpenFilter.
                                    sharpenFilterEnabled.value,
                                ),
                                desc.FloatParam(
                                    name='contrast',
                                    label='Contrast',
                                    description='Sharpen Contrast.',
                                    value=1.0,
                                    range=(0.0, 100.0, 0.1),
                                    uid=[0],
                                    enabled=lambda node: node.sharpenFilter.
                                    sharpenFilterEnabled.value,
                                ),
                                desc.FloatParam(
                                    name='threshold',
                                    label='Threshold',
                                    description='Sharpen Threshold.',
                                    value=0.0,
                                    range=(0.0, 1.0, 0.01),
                                    uid=[0],
                                    enabled=lambda node: node.sharpenFilter.
                                    sharpenFilterEnabled.value,
                                ),
                            ]),
        desc.GroupAttribute(
            name="bilateralFilter",
            label="Bilateral Filter",
            description="Bilateral Filtering Parameters.",
            joinChar=":",
            groupDesc=[
                desc.BoolParam(
                    name='bilateralFilterEnabled',
                    label='Enable',
                    description='Bilateral Filter.',
                    value=False,
                    uid=[0],
                ),
                desc.IntParam(
                    name='bilateralFilterDistance',
                    label='Distance',
                    description=
                    'Diameter of each pixel neighborhood that is used during bilateral filtering.\nCould be very slow for large filters, so it is recommended to use 5.',
                    value=0,
                    range=(0, 9, 1),
                    uid=[0],
                    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),
                    uid=[0],
                    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),
                    uid=[0],
                    enabled=lambda node: node.bilateralFilter.
                    bilateralFilterEnabled.value,
                ),
            ]),
        desc.GroupAttribute(
            name="claheFilter",
            label="Clahe Filter",
            description="Clahe Filtering Parameters.",
            joinChar=":",
            groupDesc=[
                desc.BoolParam(
                    name='claheEnabled',
                    label='Enable',
                    description=
                    'Use Contrast Limited Adaptive Histogram Equalization (CLAHE) Filter.',
                    value=False,
                    uid=[0],
                ),
                desc.FloatParam(
                    name='claheClipLimit',
                    label='Clip Limit',
                    description='Sets Threshold For Contrast Limiting.',
                    value=4.0,
                    range=(0.0, 8.0, 1.0),
                    uid=[0],
                    enabled=lambda node: node.claheFilter.claheEnabled.value,
                ),
                desc.IntParam(
                    name='claheTileGridSize',
                    label='Tile Grid Size',
                    description=
                    'Sets Size Of Grid For Histogram Equalization. Input Image Will Be Divided Into Equally Sized Rectangular Tiles.',
                    value=8,
                    range=(4, 64, 4),
                    uid=[0],
                    enabled=lambda node: node.claheFilter.claheEnabled.value,
                ),
            ]),
        desc.GroupAttribute(
            name="noiseFilter",
            label="Noise Filter",
            description="Noise Filtering Parameters.",
            joinChar=":",
            groupDesc=[
                desc.BoolParam(
                    name='noiseEnabled',
                    label='Enable',
                    description='Add Noise.',
                    value=False,
                    uid=[0],
                ),
                desc.ChoiceParam(
                    name='noiseMethod',
                    label='Method',
                    description=
                    " * method: There are several noise types to choose from:\n"
                    " * uniform: adds noise values uninformly 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'],
                    exclusive=True,
                    uid=[0],
                    enabled=lambda node: node.noiseFilter.noiseEnabled.value,
                ),
                desc.FloatParam(
                    name='noiseA',
                    label='A',
                    description=
                    'Parameter that have a different interpretation depending on the method chosen.',
                    value=0.0,
                    range=(0.0, 1.0, 0.0001),
                    uid=[0],
                    enabled=lambda node: node.noiseFilter.noiseEnabled.value,
                ),
                desc.FloatParam(
                    name='noiseB',
                    label='B',
                    description=
                    'Parameter that have a different interpretation depending on the method chosen.',
                    value=1.0,
                    range=(0.0, 1.0, 0.0001),
                    uid=[0],
                    enabled=lambda node: node.noiseFilter.noiseEnabled.value,
                ),
                desc.BoolParam(
                    name='noiseMono',
                    label='Mono',
                    description=
                    'If is Checked, a single noise value will be applied to all channels otherwise a separate noise value will be computed for each channel.',
                    value=True,
                    uid=[0],
                    enabled=lambda node: node.noiseFilter.noiseEnabled.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'],
            exclusive=True,
            uid=[0],
        ),
        desc.ChoiceParam(
            name='storageDataType',
            label='Storage Data Type for EXR output',
            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',
            value='float',
            values=['float', 'half', 'halfFinite', 'auto'],
            exclusive=True,
            uid=[0],
        ),
        desc.ChoiceParam(
            name='verboseLevel',
            label='Verbose Level',
            description=
            'verbosity level (fatal, error, warning, info, debug, trace).',
            value='info',
            values=['fatal', 'error', 'warning', 'info', 'debug', 'trace'],
            exclusive=True,
            uid=[],
        )
    ]

    outputs = [
        desc.File(
            name='outSfMData',
            label='Output sfmData',
            description='Output sfmData.',
            value=lambda attr: (desc.Node.internalFolder + os.path.basename(
                attr.node.input.value)) if (os.path.splitext(
                    attr.node.input.value)[1] in ['.abc', '.sfm']) else '',
            uid=[],
            group='',  # do not export on the command line
        ),
        desc.File(
            name='output',
            label='Output Folder',
            description='Output Images Folder.',
            value=desc.Node.internalFolder,
            uid=[],
        ),
        desc.File(
            name='outputImages',
            label='Output Images',
            description='Output Image Files.',
            value=outputImagesValueFunct,
            group='',  # do not export on the command line
            uid=[],
        ),
    ]
示例#14
0
class SfMAlignment(desc.CommandLineNode):
    commandLine = 'aliceVision_utils_sfmAlignment {allParams}'
    size = desc.DynamicNodeSize('input')

    inputs = [
        desc.File(
            name='input',
            label='Input',
            description='''SfMData file .''',
            value='',
            uid=[0],
        ),
        desc.File(
            name='reference',
            label='Reference',
            description=
            '''Path to the scene used as the reference coordinate system.''',
            value='',
            uid=[0],
        ),
        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",
            value='from_cameras_viewid',
            values=[
                'from_cameras_viewid', 'from_cameras_poseid',
                'from_cameras_filepath', 'from_cameras_metadata',
                'from_markers'
            ],
            exclusive=True,
            uid=[0],
        ),
        desc.StringParam(
            name='fileMatchingPattern',
            label='File Matching Pattern',
            description=
            'Matching regular expression for the "from_cameras_filepath" method. '
            'You should capture specific parts of the filepath with parenthesis to define matching elements.\n'
            'Some examples of patterns:\n'
            ' - Match the filename without extension (default value): ".*\/(.*?)\.\w{3}"\n'
            ' - Match the filename suffix after "_": ".*\/.*(_.*?\.\w{3})"\n'
            ' - Match the filename prefix before "_": ".*\/(.*?)_.*\.\w{3}"\n',
            value='.*\/(.*?)\.\w{3}',
            uid=[0],
        ),
        desc.ListAttribute(
            elementDesc=desc.File(
                name="metadataMatching",
                label="Metadata",
                description="",
                value="",
                uid=[0],
            ),
            name="metadataMatchingList",
            label="Metadata Matching List",
            description=
            'List of metadata that should match to create the correspondences. 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,
                       uid=[0]),
        desc.BoolParam(name='applyRotation',
                       label='Rotation',
                       description='Apply rotation transformation.',
                       value=True,
                       uid=[0]),
        desc.BoolParam(name='applyTranslation',
                       label='Translation',
                       description='Apply translation transformation.',
                       value=True,
                       uid=[0]),
        desc.ChoiceParam(
            name='verboseLevel',
            label='Verbose Level',
            description=
            '''verbosity level (fatal, error, warning, info, debug, trace).''',
            value='info',
            values=['fatal', 'error', 'warning', 'info', 'debug', 'trace'],
            exclusive=True,
            uid=[],
        ),
    ]

    outputs = [
        desc.File(
            name='output',
            label='Output',
            description='''Aligned SfMData file .''',
            value=desc.Node.internalFolder + 'alignedSfM.abc',
            uid=[],
        ),
    ]
示例#15
0
class SfMTransform(desc.CommandLineNode):
    commandLine = 'aliceVision_utils_sfmTransform {allParams}'
    size = desc.DynamicNodeSize('input')

    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

'''

    inputs = [
        desc.File(
            name='input',
            label='Input',
            description='''SfMData file .''',
            value='',
            uid=[0],
        ),
        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_from_cameras: Use cameras\n"
                        " * auto_from_landmarks: Use landmarks\n"
                        " * from_single_camera: Use a specific camera as the origin of the coordinate system\n"
                        " * from_markers: Align specific markers to custom coordinates",
            value='auto_from_landmarks',
            values=['transformation', 'manual', 'auto_from_cameras', 'auto_from_landmarks', 'from_single_camera', 'from_markers'],
            exclusive=True,
            uid=[0],
        ),
        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 image filename",
            value='',
            uid=[0],
            enabled=lambda node: node.method.value == "transformation" or node.method.value == "from_single_camera",
        ),
        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,
                            uid=[0],
                            range=(-20.0, 20.0, 0.01)
                        ),
                        desc.FloatParam(
                            name="y", label="y", description="Y Offset",
                            value=0.0,
                            uid=[0],
                            range=(-20.0, 20.0, 0.01)
                        ),
                        desc.FloatParam(
                            name="z", label="z", description="Z Offset",
                            value=0.0,
                            uid=[0],
                            range=(-20.0, 20.0, 0.01)
                        )
                    ],
                    joinChar=","
                ),
                desc.GroupAttribute(
                    name="manualRotation",
                    label="Euler Rotation",
                    description="Rotation in Euler degrees.",
                    groupDesc=[
                        desc.FloatParam(
                            name="x", label="x", description="Euler X Rotation",
                            value=0.0,
                            uid=[0],
                            range=(-90.0, 90.0, 1)
                        ),
                        desc.FloatParam(
                            name="y", label="y", description="Euler Y Rotation",
                            value=0.0,
                            uid=[0],
                            range=(-180.0, 180.0, 1)
                        ),
                        desc.FloatParam(
                            name="z", label="z", description="Euler Z Rotation",
                            value=0.0,
                            uid=[0],
                            range=(-180.0, 180.0, 1)
                        )
                    ],
                    joinChar=","
                ),
                desc.FloatParam(
                    name="manualScale",
                    label="Scale",
                    description="Uniform Scale.",
                    value=1.0,
                    uid=[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).',
            value=['sift', 'dspsift', 'akaze'],
            values=['sift', 'sift_float', 'sift_upright', 'dspsift', 'akaze', 'akaze_liop', 'akaze_mldb', 'cctag3', 'cctag4', 'sift_ocv', 'akaze_ocv', 'unknown'],
            exclusive=False,
            uid=[0],
            joinChar=',',
        ),
        desc.FloatParam(
            name='scale',
            label='Additional Scale',
            description='Additional scale to apply.',
            value=1.0,
            range=(0.0, 100.0, 0.1),
            uid=[0],
        ),
        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, uid=[0], range=(0, 32, 1)),
                desc.GroupAttribute(name="markerCoord", label="Coord", description="", joinChar=",", groupDesc=[
                    desc.FloatParam(name="x", label="x", description="", value=0.0, uid=[0], range=(-2.0, 2.0, 1.0)),
                    desc.FloatParam(name="y", label="y", description="", value=0.0, uid=[0], range=(-2.0, 2.0, 1.0)),
                    desc.FloatParam(name="z", label="z", description="", value=0.0, uid=[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,
            uid=[0],
            enabled=lambda node: node.method.value != "manual",
        ),
        desc.BoolParam(
            name='applyRotation',
            label='Rotation',
            description='Apply rotation transformation.',
            value=True,
            uid=[0],
            enabled=lambda node: node.method.value != "manual",
        ),
        desc.BoolParam(
            name='applyTranslation',
            label='Translation',
            description='Apply translation transformation.',
            value=True,
            uid=[0],
            enabled=lambda node: node.method.value != "manual",
        ),
        desc.ChoiceParam(
            name='verboseLevel',
            label='Verbose Level',
            description='''verbosity level (fatal, error, warning, info, debug, trace).''',
            value='info',
            values=['fatal', 'error', 'warning', 'info', 'debug', 'trace'],
            exclusive=True,
            uid=[],
        ),
    ]

    outputs = [
        desc.File(
            name='output',
            label='Output SfMData File',
            description='''Aligned SfMData file .''',
            value=lambda attr: desc.Node.internalFolder + (os.path.splitext(os.path.basename(attr.node.input.value))[0] or 'sfmData') + '.abc',
            uid=[],
        ),
        desc.File(
            name='outputViewsAndPoses',
            label='Output Poses',
            description='''Path to the output sfmdata file with cameras (views and poses).''',
            value=desc.Node.internalFolder + 'cameras.sfm',
            uid=[],
        ),
    ]
示例#16
0
class LdrToHdrMerge(desc.CommandLineNode):
    commandLine = 'aliceVision_LdrToHdrMerge {allParams}'
    size = desc.DynamicNodeSize('input')
    parallelization = desc.Parallelization(blockSize=2)
    commandLineRange = '--rangeStart {rangeStart} --rangeSize {rangeBlockSize}'

    documentation = '''
    Calibrate LDR to HDR response curve from samples
'''

    inputs = [
        desc.File(
            name='input',
            label='Input',
            description='SfMData file.',
            value='',
            uid=[0],
        ),
        desc.File(
            name='response',
            label='Response file',
            description='Response file',
            value='',
            uid=[0],
        ),
        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),
            uid=[],
            group='user',  # not used directly on the command line
        ),
        desc.IntParam(
            name='nbBrackets',
            label='Automatic Nb Brackets',
            description=
            'Number of exposure brackets used per HDR image. It is detected automatically from input Viewpoints metadata if "userNbBrackets" is 0, else it is equal to "userNbBrackets".',
            value=0,
            range=(0, 10, 1),
            uid=[0],
        ),
        desc.IntParam(
            name='offsetRefBracketIndex',
            label='Offset Ref Bracket Index',
            description=
            'Zero to use the center bracket. +N to use a more exposed bracket or -N to use a less exposed backet.',
            value=1,
            range=(-4, 4, 1),
            uid=[0],
            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,
            uid=[0],
            enabled=lambda node: node.nbBrackets.value != 1,
        ),
        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'],
            exclusive=True,
            uid=[0],
            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),
            uid=[0],
            advanced=True,
            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 hdr fusion.\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),
            uid=[0],
            enabled=lambda node: node.byPass.enabled and not node.byPass.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),
            uid=[0],
            enabled=lambda node: node.byPass.enabled and not node.byPass.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\n',
            value='float',
            values=['float', 'half', 'halfFinite', 'auto'],
            exclusive=True,
            uid=[0],
        ),
        desc.ChoiceParam(
            name='verboseLevel',
            label='Verbose Level',
            description=
            'verbosity level (fatal, error, warning, info, debug, trace).',
            value='info',
            values=['fatal', 'error', 'warning', 'info', 'debug', 'trace'],
            exclusive=True,
            uid=[],
        )
    ]

    outputs = [
        desc.File(
            name='outSfMData',
            label='Output SfMData File',
            description='Path to the output sfmdata file',
            value=desc.Node.internalFolder + 'sfmData.sfm',
            uid=[],
        )
    ]

    @classmethod
    def update(cls, node):
        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
        if node.userNbBrackets.value != 0:
            node.nbBrackets.value = node.userNbBrackets.value
            return
        # logging.info("[LDRToHDR] Update start: version:" + str(node.packageVersion))
        cameraInitOutput = node.input.getLinkParam(recursive=True)
        if not cameraInitOutput:
            node.nbBrackets.value = 0
            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

        # logging.info("[LDRToHDR] Update start: nb viewpoints:" + str(len(viewpoints)))
        inputs = []
        for viewpoint in viewpoints:
            jsonMetadata = viewpoint.metadata.value
            if not jsonMetadata:
                # no metadata, we cannot found the number of brackets
                node.nbBrackets.value = 0
                return
            d = json.loads(jsonMetadata)
            fnumber = findMetadata(
                d,
                ["FNumber", "Exif:ApertureValue", "ApertureValue", "Aperture"],
                "")
            shutterSpeed = findMetadata(d, [
                "Exif:ShutterSpeedValue", "ShutterSpeedValue", "ShutterSpeed"
            ], "")
            iso = findMetadata(
                d, ["Exif:ISOSpeedRatings", "ISOSpeedRatings", "ISO"], "")
            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
            inputs.append((viewpoint.path.value, (fnumber, shutterSpeed, iso)))
        inputs.sort()

        exposureGroups = []
        exposures = []
        for path, exp in inputs:
            if exposures and exp != exposures[-1] and exp == exposures[0]:
                exposureGroups.append(exposures)
                exposures = [exp]
            else:
                exposures.append(exp)
        exposureGroups.append(exposures)
        exposures = None
        bracketSizes = set()
        if len(exposureGroups) == 1:
            if len(set(exposureGroups[0])) == 1:
                # Single exposure and multiple views
                node.nbBrackets.value = 1
            else:
                # Single view and multiple exposures
                node.nbBrackets.value = len(exposureGroups[0])
        else:
            for expGroup in exposureGroups:
                bracketSizes.add(len(expGroup))
            if len(bracketSizes) == 1:
                node.nbBrackets.value = bracketSizes.pop()
                # logging.info("[LDRToHDR] nb bracket size:" + str(node.nbBrackets.value))
            else:
                node.nbBrackets.value = 0
示例#17
0
class ImageMatching(desc.CommandLineNode):
    commandLine = 'aliceVision_imageMatching {allParams}'
    size = desc.DynamicNodeSize('input')

    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='Input',
            description='SfMData file .',
            value='',
            uid=[0],
        ),
        desc.ListAttribute(
            elementDesc=desc.File(
                name="featuresFolder",
                label="Features Folder",
                description="",
                value="",
                uid=[0],
            ),
            name="featuresFolders",
            label="Features Folders",
            description=
            "Folder(s) containing the extracted features and descriptors."),
        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='VocabularyTree',
            values=[
                'VocabularyTree', 'Sequential', 'SequentialAndVocabularyTree',
                'Exhaustive', 'Frustum', 'FrustumOrVocabularyTree'
            ],
            exclusive=True,
            uid=[0],
        ),
        desc.File(
            name='tree',
            label='Voc Tree: Tree',
            description='Input name for the vocabulary tree file.',
            value=os.environ.get('ALICEVISION_VOCTREE', ''),
            uid=[],
            enabled=lambda node: 'VocabularyTree' in node.method.value,
        ),
        desc.File(
            name='weights',
            label='Voc Tree: Weights',
            description=
            'Input name for the weight file, if not provided the weights will be computed on the database built with the provided set.',
            value='',
            uid=[0],
            advanced=True,
            enabled=lambda node: 'VocabularyTree' in node.method.value,
        ),
        desc.IntParam(
            name='minNbImages',
            label='Voc Tree: Minimal Number of Images',
            description=
            'Minimal number of images to use the vocabulary tree. If we have less features than this threshold, we will compute all matching combinations.',
            value=200,
            range=(0, 500, 1),
            uid=[0],
            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. Zero means no limit.',
            value=500,
            range=(0, 100000, 1),
            uid=[0],
            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=50,
            range=(0, 1000, 1),
            uid=[0],
            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=50,
            range=(0, 1000, 1),
            uid=[0],
            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).',
            value='info',
            values=['fatal', 'error', 'warning', 'info', 'debug', 'trace'],
            exclusive=True,
            uid=[],
        )
    ]

    outputs = [
        desc.File(
            name='output',
            label='Output List File',
            description=
            'Filepath to the output file with the list of selected image pairs.',
            value=desc.Node.internalFolder + 'imageMatches.txt',
            uid=[],
        ),
    ]
示例#18
0
class PanoramaEstimation(desc.CommandLineNode):
    commandLine = 'aliceVision_panoramaEstimation {allParams}'
    size = desc.DynamicNodeSize('input')

    documentation = '''
Estimate relative camera rotations between input images.
'''

    inputs = [
        desc.File(
            name='input',
            label='Input',
            description="SfM Data File",
            value='',
            uid=[0],
        ),
        desc.ListAttribute(
            elementDesc=desc.File(
                name='featuresFolder',
                label='Features Folder',
                description="",
                value='',
                uid=[0],
            ),
            name='featuresFolders',
            label='Features Folders',
            description="Folder(s) containing the extracted features."
        ),
        desc.ListAttribute(
            elementDesc=desc.File(
                name='matchesFolder',
                label='Matches Folder',
                description="",
                value='',
                uid=[0],
            ),
            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.',
            value=['sift'],
            values=['sift', 'sift_float', 'sift_upright', 'dspsift', 'akaze', 'akaze_liop', 'akaze_mldb', 'cctag3', 'cctag4',
                    'sift_ocv', 'akaze_ocv'],
            exclusive=False,
            uid=[0],
            joinChar=',',
        ),
        desc.FloatParam(
            name='offsetLongitude',
            label='Longitude offset (deg.)',
            description='''Offset to the panorama longitude''',
            value=0.0,
            range=(-180.0, 180.0, 1.0),
            uid=[0],
        ),
        desc.FloatParam(
            name='offsetLatitude',
            label='Latitude offset (deg.)',
            description='''Offset to the panorama latitude''',
            value=0.0,
            range=(-90.0, 90.0, 1.0),
            uid=[0],
        ),
        desc.ChoiceParam(
            name='rotationAveraging',
            label='Rotation Averaging Method',
            description="Method for rotation averaging :\n"
                        " * L1 minimization\n"
                        " * L2 minimization\n",
            values=['L1_minimization', 'L2_minimization'],
            value='L2_minimization',
            exclusive=True,
            uid=[0],
            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',
            exclusive=True,
            uid=[0],
            advanced=True,
        ),
        desc.BoolParam(
            name='refine',
            label='Refine',
            description='Refine camera relative poses, points and optionally internal camera parameter',
            value=True,
            uid=[0],
        ),
        desc.BoolParam(
            name='lockAllIntrinsics',
            label='Force Lock of All Intrinsics',
            description='Force to keep constant all the intrinsics parameters of the cameras (focal length, \n'
                        'principal point, distortion if any) during the reconstruction.\n'
                        'This may be helpful if the input cameras are already fully calibrated.',
            value=False,
            uid=[0],
        ),
        desc.FloatParam(
            name='maxAngleToPrior',
            label='Max Angle To Priors (deg.)',
            description='''Maximal angle allowed regarding the input prior (in degrees).''',
            value=20.0,
            range=(0.0, 360.0, 1.0),
            uid=[0],
            advanced=True,
        ),
        desc.FloatParam(
            name='maxAngularError',
            label='Max Angular Error (deg.)',
            description='''Maximal angular error in global rotation averging (in degrees).''',
            value=100.0,
            range=(0.0, 360.0, 1.0),
            uid=[0],
            advanced=True,
        ),
        desc.BoolParam(
            name='intermediateRefineWithFocal',
            label='Intermediate Refine: Focal',
            description='Intermediate refine with rotation and focal length only.',
            value=False,
            uid=[0],
            advanced=True,
        ),
        desc.BoolParam(
            name='intermediateRefineWithFocalDist',
            label='Intermediate Refine: Focal And Distortion',
            description='Intermediate refine with rotation, focal length and distortion.',
            value=False,
            uid=[0],
            advanced=True,
        ),
        desc.ChoiceParam(
            name='verboseLevel',
            label='Verbose Level',
            description='Verbosity level (fatal, error, warning, info, debug, trace).',
            value='info',
            values=['fatal', 'error', 'warning', 'info', 'debug', 'trace'],
            exclusive=True,
            uid=[],
        ),
    ]

    outputs = [
        desc.File(
            name='output',
            label='Output SfMData File',
            description='Path to the output sfmdata file',
            value=desc.Node.internalFolder + 'panorama.abc',
            uid=[],
        ),
        desc.File(
            name='outputViewsAndPoses',
            label='Output Poses',
            description='''Path to the output sfmdata file with cameras (views and poses).''',
            value=desc.Node.internalFolder + 'cameras.sfm',
            uid=[],
        ),
    ]
示例#19
0
class ConvertSfMFormat(desc.CommandLineNode):
    commandLine = 'aliceVision_convertSfMFormat {allParams}'
    size = desc.DynamicNodeSize('input')

    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='SfMData file.',
            value='',
            uid=[0],
        ),
        desc.ChoiceParam(
            name='fileExt',
            label='SfM File Format',
            description='SfM File Format',
            value='abc',
            values=['abc', 'sfm', 'json', 'ply', 'baf'],
            exclusive=True,
            uid=[0],
            group='',  # exclude from command line
        ),
        desc.ChoiceParam(
            name='describerTypes',
            label='Describer Types',
            description='Describer types to keep.',
            value=['sift'],
            values=['sift', 'sift_float', 'sift_upright', 'dspsift', 'akaze', 'akaze_liop', 'akaze_mldb', 'cctag3', 'cctag4', 'sift_ocv', 'akaze_ocv', 'unknown'],
            exclusive=False,
            uid=[0],
            joinChar=',',
        ),
        desc.ListAttribute(
            elementDesc=desc.File(
                name="imageId",
                label="Image id",
                description="",
                value="",
                uid=[0],
            ),
            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,
            uid=[0],
        ),
        desc.BoolParam(
            name='intrinsics',
            label='Intrinsics',
            description='Export intrinsics.',
            value=True,
            uid=[0],
        ),
        desc.BoolParam(
            name='extrinsics',
            label='Extrinsics',
            description='Export extrinsics.',
            value=True,
            uid=[0],
        ),
        desc.BoolParam(
            name='structure',
            label='Structure',
            description='Export structure.',
            value=True,
            uid=[0],
        ),
        desc.BoolParam(
            name='observations',
            label='Observations',
            description='Export observations.',
            value=True,
            uid=[0],
        ),
        desc.ChoiceParam(
            name='verboseLevel',
            label='Verbose Level',
            description='verbosity level (fatal, error, warning, info, debug, trace).',
            value='info',
            values=['fatal', 'error', 'warning', 'info', 'debug', 'trace'],
            exclusive=True,
            uid=[0],
        ),
    ]

    outputs = [
        desc.File(
            name='output',
            label='Output',
            description='Path to the output SfM Data file.',
            value=desc.Node.internalFolder + 'sfm.{fileExtValue}',
            uid=[],
            ),
    ]
示例#20
0
class PanoramaInit(desc.CommandLineNode):
    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='Input',
            description="SfM Data File",
            value='',
            uid=[0],
        ),
        desc.ChoiceParam(
            name='initializeCameras',
            label='Initialize Cameras',
            description='Initialize cameras.',
            value='No',
            values=['No', 'File', 'Horizontal', 'Horizontal+Zenith', 'Zenith+Horizontal', 'Spherical'],
            exclusive=True,
            uid=[0],
        ),
        desc.File(
            name='config',
            label='Xml Config',
            description="XML Data File",
            value='',
            uid=[0],
            enabled=lambda node: node.initializeCameras.value == 'File',
        ),
        desc.BoolParam(
            name='yawCW',
            label='Yaw CW',
            description="Yaw ClockWise or CounterClockWise",
            value=1,
            uid=[0],
            enabled=lambda node: ('Horizontal' in node.initializeCameras.value) or (node.initializeCameras.value == "Spherical"),
        ),
        desc.ListAttribute(
            elementDesc=desc.IntParam(
                name='nbViews',
                label='',
                description='',
                value=-1,
                range=[-1, 20],
                uid=[0],
            ),
            name='nbViewsPerLine',
            label='Spherical: Nb Views Per Line',
            description='Number of views per line in Spherical acquisition. Assumes angles from [-90,+90deg] for pitch and [-180,+180deg] for yaw. Use -1 to estimate the number of images automatically.',
            joinChar=',',
            enabled=lambda node: node.initializeCameras.value == 'Spherical',
        ),
        desc.ListAttribute(
            elementDesc=desc.File(
                name='dependency',
                label='',
                description="",
                value='',
                uid=[],
            ),
            name='dependency',
            label='Dependency',
            description="Folder(s) in which computed features are stored. (WORKAROUND for valid Tractor graph submission)",
            group='forDependencyOnly', # not a command line argument
        ),
        desc.BoolParam(
            name='useFisheye',
            label='Full Fisheye',
            description='To declare a full fisheye panorama setup',
            value=False,
            uid=[0],
        ),
        desc.BoolParam(
            name='estimateFisheyeCircle',
            label='Estimate Fisheye Circle',
            description='Automatically estimate the Fisheye Circle center and radius instead of using user values.',
            value=True,
            uid=[0],
            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,
                    uid=[0],
                    range=(-1000.0, 10000.0, 1.0)),
                desc.FloatParam(
                    name="fisheyeCenterOffset_y", label="y", description="Y Offset in pixels",
                    value=0.0,
                    uid=[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='Radius',
            description='Fisheye visibillity circle radius (% of image shortest side).',
            value=96.0,
            range=(0.0, 150.0, 0.01),
            uid=[0],
            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'],
            exclusive=True,
            uid=[0]
        ),
        desc.BoolParam(
            name='debugFisheyeCircleEstimation',
            label='Debug Fisheye Circle Detection',
            description='Debug fisheye circle detection.',
            value=False,
            uid=[0],
            enabled=lambda node: node.useFisheye.value,
            advanced=True,
        ),
        desc.ChoiceParam(
            name='verboseLevel',
            label='Verbose Level',
            description='Verbosity level (fatal, error, warning, info, debug, trace).',
            value='info',
            values=['fatal', 'error', 'warning', 'info', 'debug', 'trace'],
            exclusive=True,
            uid=[],
        ),
    ]

    outputs = [
        desc.File(
            name='outSfMData',
            label='Output SfMData File',
            description='Path to the output sfmdata file',
            value=desc.Node.internalFolder + 'sfmData.sfm',
            uid=[],
        )
    ]
示例#21
0
class DepthMap(desc.CommandLineNode):
    commandLine = 'aliceVision_depthMapEstimation {allParams}'
    gpu = desc.Level.INTENSIVE
    size = desc.DynamicNodeSize('ini')
    parallelization = desc.Parallelization(blockSize=3)
    commandLineRange = '--rangeStart {rangeStart} --rangeSize {rangeBlockSize}'

    inputs = [
        desc.File(
            name="ini",
            label='MVS Configuration File',
            description='',
            value='',
            uid=[0],
        ),
        desc.ChoiceParam(
            name='downscale',
            label='Downscale',
            description='Image downscale factor.',
            value=2,
            values=[1, 2, 4, 8, 16],
            exclusive=True,
            uid=[0],
        ),
        desc.IntParam(
            name='sgmMaxTCams',
            label='SGM: Nb Neighbour Cameras',
            description='Semi Global Matching: Number of neighbour cameras.',
            value=10,
            range=(1, 100, 1),
            uid=[0],
        ),
        desc.IntParam(
            name='sgmWSH',
            label='SGM: WSH',
            description=
            'Semi Global Matching: Half-size of the patch used to compute the similarity.',
            value=4,
            range=(1, 20, 1),
            uid=[0],
        ),
        desc.FloatParam(
            name='sgmGammaC',
            label='SGM: GammaC',
            description='Semi Global Matching: GammaC Threshold.',
            value=5.5,
            range=(0.0, 30.0, 0.5),
            uid=[0],
        ),
        desc.FloatParam(
            name='sgmGammaP',
            label='SGM: GammaP',
            description='Semi Global Matching: GammaP Threshold.',
            value=8.0,
            range=(0.0, 30.0, 0.5),
            uid=[0],
        ),
        desc.IntParam(
            name='refineNSamplesHalf',
            label='Refine: Number of Samples',
            description='Refine: Number of samples.',
            value=150,
            range=(1, 500, 10),
            uid=[0],
        ),
        desc.IntParam(
            name='refineNDepthsToRefine',
            label='Refine: Number of Depths',
            description='Refine: Number of depths.',
            value=31,
            range=(1, 100, 1),
            uid=[0],
        ),
        desc.IntParam(
            name='refineNiters',
            label='Refine: Number of Iterations',
            description='Refine:: Number of iterations.',
            value=100,
            range=(1, 500, 10),
            uid=[0],
        ),
        desc.IntParam(
            name='refineWSH',
            label='Refine: WSH',
            description=
            'Refine: Half-size of the patch used to compute the similarity.',
            value=3,
            range=(1, 20, 1),
            uid=[0],
        ),
        desc.IntParam(
            name='refineMaxTCams',
            label='Refine: Nb Neighbour Cameras',
            description='Refine: Number of neighbour cameras.',
            value=6,
            range=(1, 20, 1),
            uid=[0],
        ),
        desc.FloatParam(
            name='refineSigma',
            label='Refine: Sigma',
            description='Refine: Sigma Threshold.',
            value=15,
            range=(0.0, 30.0, 0.5),
            uid=[0],
        ),
        desc.FloatParam(
            name='refineGammaC',
            label='Refine: GammaC',
            description='Refine: GammaC Threshold.',
            value=15.5,
            range=(0.0, 30.0, 0.5),
            uid=[0],
        ),
        desc.FloatParam(
            name='refineGammaP',
            label='Refine: GammaP',
            description='Refine: GammaP threshold.',
            value=8.0,
            range=(0.0, 30.0, 0.5),
            uid=[0],
        ),
        desc.BoolParam(
            name='refineUseTcOrRcPixSize',
            label='Refine: Tc or Rc pixel size',
            description=
            'Refine: Use minimum pixel size of neighbour cameras (Tc) or current camera pixel size (Rc)',
            value=False,
            uid=[0],
        ),
        desc.ChoiceParam(
            name='verboseLevel',
            label='Verbose Level',
            description=
            '''verbosity level (fatal, error, warning, info, debug, trace).''',
            value='info',
            values=['fatal', 'error', 'warning', 'info', 'debug', 'trace'],
            exclusive=True,
            uid=[],
        ),
    ]

    outputs = [
        desc.File(
            name='output',
            label='Output',
            description='Output folder for generated depth maps.',
            value=desc.Node.internalFolder,
            uid=[],
        ),
    ]
class StructureFromMotion(desc.CommandLineNode):
    commandLine = 'aliceVision_incrementalSfM {allParams}'
    size = desc.DynamicNodeSize('input')

    inputs = [
        desc.File(
            name='input',
            label='Input',
            description='SfMData file.',
            value='',
            uid=[0],
        ),
        desc.ListAttribute(
            elementDesc=desc.File(
                name="featuresFolder",
                label="Features Folder",
                description="",
                value="",
                uid=[0],
            ),
            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="",
                value="",
                uid=[0],
            ),
            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.',
            value=['sift'],
            values=['sift', 'sift_float', 'sift_upright', 'akaze', 'akaze_liop', 'akaze_mldb', 'cctag3', 'cctag4', 'sift_ocv', 'akaze_ocv'],
            exclusive=False,
            uid=[0],
            joinChar=',',
        ),
        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'],
            exclusive=True,
            uid=[0],
        ),
       desc.BoolParam(
            name='lockScenePreviouslyReconstructed',
            label='Lock Scene Previously Reconstructed',
            description='This option is useful for SfM augmentation. Lock previously reconstructed poses and intrinsics.',
            value=False,
            uid=[0],
        ),
        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,
            uid=[0],
        ),
        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),
            uid=[0],
        ),
        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),
            uid=[0],
        ),
        desc.IntParam(
            name='minInputTrackLength',
            label='Min Input Track Length',
            description='Minimum track length in input of SfM',
            value=2,
            range=(2, 10, 1),
            uid=[0],
        ),
        desc.IntParam(
            name='minNumberOfObservationsForTriangulation',
            label='Min Observation For Triangulation',
            description='Minimum number of observations to triangulate a point.\n'
                        'Set 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),
            uid=[0],
        ),
        desc.FloatParam(
            name='minAngleForTriangulation',
            label='Min Angle For Triangulation',
            description='Minimum angle for triangulation.',
            value=3.0,
            range=(0.1, 10, 0.1),
            uid=[0],
        ),
        desc.FloatParam(
            name='minAngleForLandmark',
            label='Min Angle For Landmark',
            description='Minimum angle for landmark.',
            value=2.0,
            range=(0.1, 10, 0.1),
            uid=[0],
        ),
        desc.FloatParam(
            name='maxReprojectionError',
            label='Max Reprojection Error',
            description='Maximum reprojection error.',
            value=4.0,
            range=(0.1, 10, 0.1),
            uid=[0],
        ),
        desc.FloatParam(
            name='minAngleInitialPair',
            label='Min Angle Initial Pair',
            description='Minimum angle for the initial pair.',
            value=5.0,
            range=(0.1, 10, 0.1),
            uid=[0],
        ),
        desc.FloatParam(
            name='maxAngleInitialPair',
            label='Max Angle Initial Pair',
            description='Maximum angle for the initial pair.',
            value=40.0,
            range=(0.1, 60, 0.1),
            uid=[0],
        ),
        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,
            uid=[],
        ),
        desc.File(
            name='initialPairA',
            label='Initial Pair A',
            description='Filename of the first image (without path).',
            value='',
            uid=[0],
        ),
        desc.File(
            name='initialPairB',
            label='Initial Pair B',
            description='Filename of the second image (without path).',
            value='',
            uid=[0],
        ),
        desc.ChoiceParam(
            name='interFileExtension',
            label='Inter File Extension',
            description='Extension of the intermediate file export.',
            value='.abc',
            values=('.abc', '.ply'),
            exclusive=True,
            uid=[],
        ),
        desc.ChoiceParam(
            name='verboseLevel',
            label='Verbose Level',
            description='Verbosity level (fatal, error, warning, info, debug, trace).',
            value='info',
            values=['fatal', 'error', 'warning', 'info', 'debug', 'trace'],
            exclusive=True,
            uid=[],
        )
    ]

    outputs = [
        desc.File(
            name='output',
            label='Output SfMData File',
            description='Path to the output sfmdata file',
            value=desc.Node.internalFolder + 'sfm.abc',
            uid=[],
        ),
        desc.File(
            name='outputViewsAndPoses',
            label='Output SfMData File',
            description='''Path to the output sfmdata file with cameras (views and poses).''',
            value=desc.Node.internalFolder + 'cameras.sfm',
            uid=[],
        ),
        desc.File(
            name='extraInfoFolder',
            label='Output Folder',
            description='Folder for intermediate reconstruction files and additional reconstruction information files.',
            value=desc.Node.internalFolder,
            uid=[],
        ),
    ]

    @staticmethod
    def getViewsAndPoses(node):
        """
        Parse SfM result and return views and poses as two dict with viewId and poseId as keys.
        """
        reportFile = node.outputViewsAndPoses.value
        if not os.path.exists(reportFile):
            return {}, {}

        with open(reportFile) as jsonFile:
            report = json.load(jsonFile)

        views = dict()
        poses = dict()

        for view in report['views']:
            views[view['viewId']] = view

        for pose in report['poses']:
            poses[pose['poseId']] = pose['pose']

        return views, poses
示例#23
0
class SketchfabUpload(desc.Node):
    size = desc.DynamicNodeSize('inputFiles')

    documentation = '''
Upload a textured mesh on Sketchfab.
'''

    inputs = [
        desc.ListAttribute(
            elementDesc=desc.File(
                name="input",
                label="Input",
                description="",
                value="",
                uid=[0],
            ),
            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='',
            uid=[0],
        ),
        desc.StringParam(
            name='title',
            label='Title',
            description='Title cannot be longer than 48 characters.',
            value='',
            uid=[0],
        ),
        desc.StringParam(
            name='description',
            label='Description',
            description='Description cannot be longer than 1024 characters.',
            value='',
            uid=[0],
        ),
        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'
            ],
            exclusive=True,
            uid=[0],
        ),
        desc.ListAttribute(
            elementDesc=desc.StringParam(
                name='tag',
                label='Tag',
                description='Tag cannot be longer than 48 characters.',
                value='',
                uid=[0],
            ),
            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'
            ],
            exclusive=True,
            uid=[0],
        ),
        desc.BoolParam(
            name='isPublished',
            label='Publish',
            description=
            'If the model is not published it will be saved as a draft.',
            value=False,
            uid=[0],
        ),
        desc.BoolParam(
            name='isInspectable',
            label='Inspectable',
            description='Allow 2D view in model inspector.',
            value=True,
            uid=[0],
        ),
        desc.BoolParam(
            name='isPrivate',
            label='Private',
            description='Requires a pro account.',
            value=False,
            uid=[0],
        ),
        desc.StringParam(
            name='password',
            label='Password',
            description='Requires a pro account.',
            value='',
            uid=[0],
        ),
        desc.ChoiceParam(
            name='verboseLevel',
            label='Verbose Level',
            description=
            '''verbosity level (critical, error, warning, info, debug).''',
            value='info',
            values=['critical', 'error', 'warning', 'info', 'debug'],
            exclusive=True,
            uid=[],
        ),
    ]

    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 occured: {}'.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
示例#24
0
class DepthMapFilter(desc.CommandLineNode):
    commandLine = 'aliceVision_depthMapFiltering {allParams}'
    gpu = desc.Level.NORMAL
    size = desc.DynamicNodeSize('input')
    parallelization = desc.Parallelization(blockSize=10)
    commandLineRange = '--rangeStart {rangeStart} --rangeSize {rangeBlockSize}'

    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='',
            uid=[0],
        ),
        desc.File(
            name="depthMapsFolder",
            label="DepthMaps Folder",
            description="Input depth maps folder",
            value="",
            uid=[0],
        ),
        desc.FloatParam(
            name='minViewAngle',
            label='Min View Angle',
            description='Minimum angle between two views.',
            value=2.0,
            range=(0.0, 10.0, 0.1),
            uid=[0],
            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),
            uid=[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),
            uid=[0],
            advanced=True,
        ),
        desc.IntParam(
            name="minNumOfConsistentCams",
            label="Min Consistent Cameras",
            description="Min Number of Consistent Cameras",
            value=3,
            range=(0, 10, 1),
            uid=[0],
        ),
        desc.IntParam(
            name="minNumOfConsistentCamsWithLowSimilarity",
            label="Min Consistent Cameras Bad Similarity",
            description=
            "Min Number of Consistent Cameras for pixels with weak similarity value",
            value=4,
            range=(0, 10, 1),
            uid=[0],
        ),
        desc.IntParam(
            name="pixSizeBall",
            label="Filtering Size in Pixels",
            description="Filtering size in pixels",
            value=0,
            range=(0, 10, 1),
            uid=[0],
            advanced=True,
        ),
        desc.IntParam(
            name="pixSizeBallWithLowSimilarity",
            label="Filtering Size in Pixels Bad Similarity",
            description="Filtering size in pixels",
            value=0,
            range=(0, 10, 1),
            uid=[0],
            advanced=True,
        ),
        desc.BoolParam(
            name='computeNormalMaps',
            label='Compute Normal Maps',
            description='Compute normal maps per depth map.',
            value=False,
            uid=[0],
            advanced=True,
        ),
        desc.ChoiceParam(
            name='verboseLevel',
            label='Verbose Level',
            description=
            '''verbosity level (fatal, error, warning, info, debug, trace).''',
            value='info',
            values=['fatal', 'error', 'warning', 'info', 'debug', 'trace'],
            exclusive=True,
            uid=[],
        ),
    ]

    outputs = [
        desc.File(
            name='output',
            label='Filtered DepthMaps Folder',
            description='Output folder for generated depth maps.',
            value=desc.Node.internalFolder,
            uid=[],
        ),
    ]
示例#25
0
class SfMTransform(desc.CommandLineNode):
    commandLine = 'aliceVision_utils_sfmTransform {allParams}'
    size = desc.DynamicNodeSize('input')

    inputs = [
        desc.File(
            name='input',
            label='Input',
            description='''SfMData file .''',
            value='',
            uid=[0],
        ),
        desc.ChoiceParam(
            name='method',
            label='Transformation Method',
            description=
            '''Transformation method (transformation, auto_from_cameras, auto_from_landmarks).''',
            value='auto_from_landmarks',
            values=[
                'transformation', 'auto_from_cameras', 'auto_from_landmarks'
            ],
            exclusive=True,
            uid=[0],
        ),
        desc.StringParam(
            name='transformation',
            label='Transformation',
            description=
            '''Align [X,Y,Z] to +Y-axis, rotate around Y by R deg, scale by S; syntax: X,Y,Z;R;S. (required only for 'transformation' method)''',
            value='',
            uid=[0],
        ),
        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).',
            value=['sift', 'akaze'],
            values=[
                'sift', 'sift_float', 'sift_upright', 'akaze', 'akaze_liop',
                'akaze_mldb', 'cctag3', 'cctag4', 'sift_ocv', 'akaze_ocv'
            ],
            exclusive=False,
            uid=[0],
            joinChar=',',
        ),
        desc.FloatParam(
            name='scale',
            label='Additional Scale',
            description='Additional scale to apply.',
            value=10.0,
            range=(1, 100.0, 1),
            uid=[0],
        ),
        desc.ChoiceParam(
            name='verboseLevel',
            label='Verbose Level',
            description=
            '''verbosity level (fatal, error, warning, info, debug, trace).''',
            value='info',
            values=['fatal', 'error', 'warning', 'info', 'debug', 'trace'],
            exclusive=True,
            uid=[],
        ),
    ]

    outputs = [
        desc.File(
            name='output',
            label='Output',
            description='''Aligned SfMData file .''',
            value=desc.Node.internalFolder + 'transformedSfM.abc',
            uid=[],
        ),
    ]
示例#26
0
class FeatureExtraction(desc.CommandLineNode):
    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 to 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='SfMData file.',
            value='',
            uid=[0],
        ),
        desc.ChoiceParam(
            name='describerTypes',
            label='Describer Types',
            description='Describer types used to describe an image.',
            value=['sift'],
            values=['sift', 'sift_float', 'sift_upright', 'dspsift', 'akaze', 'akaze_liop', 'akaze_mldb', 'cctag3', 'cctag4', 'sift_ocv', 'akaze_ocv'],
            exclusive=False,
            uid=[0],
            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', 'custom'],
            exclusive=True,
            uid=[0],
            group=lambda node: 'allParams' if node.describerPreset.value != 'custom' else None,
        ),
        desc.IntParam(
            name='maxNbFeatures',
            label='Max Nb Features',
            description='Max number of features extracted (0 means default value based on Describer Density).',
            value=0,
            range=(0, 100000, 1000),
            uid=[0],
            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'],
            exclusive=True,
            uid=[0],
        ),
        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'],
            exclusive=True,
            advanced=True,
            uid=[0],
        ),
        desc.FloatParam(
            name='relativePeakThreshold',
            label='Relative Peak Threshold',
            description='Peak Threshold relative to median of gradiants.',
            value=0.01,
            range=(0.01, 1.0, 0.001),
            advanced=True,
            uid=[0],
            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,
            uid=[0],
        ),
        desc.BoolParam(
            name='forceCpuExtraction',
            label='Force CPU Extraction',
            description='Use only CPU feature extraction.',
            value=True,
            uid=[],
            advanced=True,
        ),
        desc.IntParam(
            name='maxThreads',
            label='Max Nb Threads',
            description='Specifies the maximum number of threads to run simultaneously (0 for automatic mode).',
            value=0,
            range=(0, 24, 1),
            uid=[],
            advanced=True,
        ),
        desc.ChoiceParam(
            name='verboseLevel',
            label='Verbose Level',
            description='verbosity level (fatal, error, warning, info, debug, trace).',
            value='info',
            values=['fatal', 'error', 'warning', 'info', 'debug', 'trace'],
            exclusive=True,
            uid=[],
        )
    ]

    outputs = [
        desc.File(
            name='output',
            label='Features Folder',
            description='Output path for the features and descriptors files (*.feat, *.desc).',
            value=desc.Node.internalFolder,
            uid=[],
        ),
    ]
示例#27
0
class PanoramaWarping(desc.CommandLineNode):
    commandLine = 'aliceVision_panoramaWarping {allParams}'
    size = desc.DynamicNodeSize('input')

    parallelization = desc.Parallelization(blockSize=5)
    commandLineRange = '--rangeStart {rangeStart} --rangeSize {rangeBlockSize}'

    documentation = '''
Compute the image warping for each input image in the panorama coordinate system.
'''

    inputs = [
        desc.File(
            name='input',
            label='Input',
            description="SfM Data File",
            value='',
            uid=[0],
        ),
        desc.BoolParam(
            name='estimateResolution',
            label='Estimate Resolution',
            description='Estimate output panorama resolution automatically based on the input images resolution.',
            value=True,
            uid=[0],
            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),
            uid=[0],
            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),
            uid=[0]
        ),
        desc.IntParam(
            name='maxPanoramaWidth',
            label='Max Panorama Width',
            description='Choose the maximal output panorama width (in pixels). Zero means no limit.',
            value=35000,
            range=(0, 100000, 1000),
            uid=[0],
            enabled=lambda node: (node.estimateResolution.value),
        ),
        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',
            value='float',
            values=['float', 'half', 'halfFinite', 'auto'],
            exclusive=True,
            uid=[0],
        ),
        desc.ChoiceParam(
            name='verboseLevel',
            label='Verbose Level',
            description='Verbosity level (fatal, error, warning, info, debug, trace).',
            value='info',
            values=['fatal', 'error', 'warning', 'info', 'debug', 'trace'],
            exclusive=True,
            uid=[],
        ),
    ]

    outputs = [
        desc.File(
            name='output',
            label='Output directory',
            description='',
            value=desc.Node.internalFolder,
            uid=[],
        ),
    ]
示例#28
0
class PanoramaMerging(desc.CommandLineNode):
    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.",
            value='',
            uid=[0],
        ),
        desc.File(
            name='compositingFolder',
            label='compositing Folder',
            description="Panorama Compositing results",
            value='',
            uid=[0],
        ),
        desc.ChoiceParam(
            name='outputFileType',
            label='Output File Type',
            description='Output file type for the undistorted images.',
            value='exr',
            values=['jpg', 'png', 'tif', 'exr'],
            exclusive=True,
            uid=[0],
            group=
            '',  # not part of allParams, as this is not a parameter for the command line
        ),
        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',
            value='float',
            values=['float', 'half', 'halfFinite', 'auto'],
            exclusive=True,
            uid=[0],
        ),
        desc.ChoiceParam(
            name='verboseLevel',
            label='Verbose Level',
            description=
            'Verbosity level (fatal, error, warning, info, debug, trace).',
            value='info',
            values=['fatal', 'error', 'warning', 'info', 'debug', 'trace'],
            exclusive=True,
            uid=[],
        ),
    ]

    outputs = [
        desc.File(
            name='outputPanorama',
            label='Output Folder',
            description='',
            value=desc.Node.internalFolder + 'panorama.{outputFileTypeValue}',
            uid=[],
        ),
    ]
示例#29
0
class FeatureMatching(desc.CommandLineNode):
    commandLine = 'aliceVision_featureMatching {allParams}'
    size = desc.DynamicNodeSize('input')
    parallelization = desc.Parallelization(blockSize=20)
    commandLineRange = '--rangeStart {rangeStart} --rangeSize {rangeBlockSize}'

    inputs = [
        desc.File(
            name='input',
            label='Input',
            description='SfMData file.',
            value='',
            uid=[0],
        ),
        desc.ListAttribute(
            elementDesc=desc.File(
                name="featuresFolder",
                label="Features Folder",
                description="",
                value="",
                uid=[0],
            ),
            name="featuresFolders",
            label="Features Folders",
            description=
            "Folder(s) containing the extracted features and descriptors."),
        desc.File(
            name='imagePairsList',
            label='Image Pairs List',
            description=
            'Path to a file which contains the list of image pairs to match.',
            value='',
            uid=[0],
        ),
        desc.ChoiceParam(
            name='describerTypes',
            label='Describer Types',
            description='Describer types used to describe an image.',
            value=['sift'],
            values=[
                'sift', 'sift_float', 'sift_upright', 'akaze', 'akaze_liop',
                'akaze_mldb', 'cctag3', 'cctag4', 'sift_ocv', 'akaze_ocv'
            ],
            exclusive=False,
            uid=[0],
            joinChar=',',
        ),
        desc.ChoiceParam(
            name='photometricMatchingMethod',
            label='Photometric Matching Method',
            description='For Scalar based regions descriptor\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 descriptor\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'),
            exclusive=True,
            uid=[0],
        ),
        desc.ChoiceParam(
            name='geometricEstimator',
            label='Geometric Estimator',
            description=
            'Geometric estimator: (acransac: A-Contrario Ransac, loransac: LO-Ransac (only available for "fundamental_matrix" model)',
            value='acransac',
            values=['acransac', 'loransac'],
            exclusive=True,
            uid=[0],
        ),
        desc.ChoiceParam(
            name='geometricFilterType',
            label='Geometric Filter Type',
            description=
            'Geometric validation method to filter features matches: \n'
            ' * fundamental_matrix\n'
            ' * essential_matrix\n'
            ' * homography_matrix\n'
            ' * homography_growing\n'
            ' * no_filtering',
            value='fundamental_matrix',
            values=[
                'fundamental_matrix', 'essential_matrix', 'homography_matrix',
                'homography_growing', 'no_filtering'
            ],
            exclusive=True,
            uid=[0],
        ),
        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),
            uid=[0],
        ),
        desc.IntParam(
            name='maxIteration',
            label='Max Iteration',
            description='Maximum number of iterations allowed in ransac step.',
            value=2048,
            range=(1, 20000, 1),
            uid=[0],
        ),
        desc.IntParam(
            name='maxMatches',
            label='Max Matches',
            description='Maximum number of matches to keep.',
            value=0,
            range=(0, 10000, 1),
            uid=[0],
        ),
        desc.BoolParam(
            name='savePutativeMatches',
            label='Save Putative Matches',
            description='putative matches.',
            value=False,
            uid=[0],
        ),
        desc.BoolParam(
            name='guidedMatching',
            label='Guided Matching',
            description=
            'the found model to improve the pairwise correspondences.',
            value=False,
            uid=[0],
        ),
        desc.BoolParam(
            name='exportDebugFiles',
            label='Export Debug Files',
            description='debug files (svg, dot).',
            value=False,
            uid=[],
        ),
        desc.ChoiceParam(
            name='verboseLevel',
            label='Verbose Level',
            description=
            'verbosity level (fatal, error, warning, info, debug, trace).',
            value='info',
            values=['fatal', 'error', 'warning', 'info', 'debug', 'trace'],
            exclusive=True,
            uid=[],
        )
    ]
    outputs = [
        desc.File(
            name='output',
            label='Output Folder',
            description=
            'Path to a folder in which computed matches will be stored.',
            value=desc.Node.internalFolder,
            uid=[],
        ),
    ]
示例#30
0
class Publish(desc.Node):
    size = desc.DynamicNodeSize('inputFiles')
    inputs = [
        desc.ListAttribute(
            elementDesc=desc.File(
                name="input",
                label="Input",
                description="",
                value="",
                uid=[0],
            ),
            name="inputFiles",
            label="Input Files",
            description="Input Files to publish.",
            group="",
        ),
        desc.File(
            name="output",
            label="Output Folder",
            description="",
            value="",
            uid=[0],
        ),
        desc.ChoiceParam(
            name='verboseLevel',
            label='Verbose Level',
            description=
            '''verbosity level (critical, error, warning, info, debug).''',
            value='info',
            values=['critical', 'error', 'warning', 'info', 'debug'],
            exclusive=True,
            uid=[],
        ),
    ]

    def resolvedPaths(self, inputFiles, outDir):
        paths = {}
        for inputFile in inputFiles:
            for f in glob.glob(inputFile.value):
                paths[f] = os.path.join(outDir, os.path.basename(f))
        return paths

    def processChunk(self, chunk):
        chunk.logManager.waitUntilCleared()
        chunk.logger.setLevel(
            chunk.logManager.textToLevel(chunk.node.verboseLevel.value))

        if not chunk.node.inputFiles:
            chunk.logger.warning('Nothing to publish')
            return
        if not chunk.node.output.value:
            return

        outFiles = self.resolvedPaths(chunk.node.inputFiles.value,
                                      chunk.node.output.value)

        if not outFiles:
            error = 'Publish: input files listed, but nothing to publish'
            chunk.logger.error(error)
            chunk.logger.info('Listed input files: {}'.format(
                [i.value for i in chunk.node.inputFiles.value]))
            raise RuntimeError(error)

        if not os.path.exists(chunk.node.output.value):
            os.mkdir(chunk.node.output.value)

        for iFile, oFile in outFiles.items():
            chunk.logger.info('Publish file {} into {}'.format(iFile, oFile))
            shutil.copyfile(iFile, oFile)
        chunk.logger.info('Publish end')