kopia lustrzana https://github.com/OpenDroneMap/ODM
Better config help, cleanup
rodzic
8e49d99939
commit
43d67019da
178
opendm/config.py
178
opendm/config.py
|
@ -76,15 +76,14 @@ def config(argv=None, parser=None):
|
|||
parser.add_argument('--project-path',
|
||||
metavar='<path>',
|
||||
action=StoreValue,
|
||||
help='Path to the project folder')
|
||||
|
||||
help='Path to the project folder. Your project folder should contain subfolders for each dataset. Each dataset should have an "images" folder.')
|
||||
parser.add_argument('name',
|
||||
metavar='<project name>',
|
||||
action=StoreValue,
|
||||
type=alphanumeric_string,
|
||||
default='code',
|
||||
nargs='?',
|
||||
help='Name of Project (i.e subdirectory of projects folder)')
|
||||
help='Name of dataset (i.e subfolder name within project folder). Default: %(default)s')
|
||||
|
||||
parser.add_argument('--resize-to',
|
||||
metavar='<integer>',
|
||||
|
@ -93,14 +92,14 @@ def config(argv=None, parser=None):
|
|||
type=int,
|
||||
help='Legacy option (use --feature-quality instead). Resizes images by the largest side for feature extraction purposes only. '
|
||||
'Set to -1 to disable. This does not affect the final orthophoto '
|
||||
'resolution quality and will not resize the original images. Default: %(default)s')
|
||||
'resolution quality and will not resize the original images. Default: %(default)s')
|
||||
|
||||
parser.add_argument('--end-with', '-e',
|
||||
metavar='<string>',
|
||||
action=StoreValue,
|
||||
default='odm_report',
|
||||
choices=processopts,
|
||||
help=('Can be one of:' + ' | '.join(processopts)))
|
||||
help='End processing at this stage. Can be one of: %(choices)s. Default: %(default)s')
|
||||
|
||||
rerun = parser.add_mutually_exclusive_group()
|
||||
|
||||
|
@ -108,27 +107,19 @@ def config(argv=None, parser=None):
|
|||
metavar='<string>',
|
||||
action=StoreValue,
|
||||
choices=processopts,
|
||||
help=('Can be one of:' + ' | '.join(processopts)))
|
||||
help=('Rerun this stage only and stop. Can be one of: %(choices)s. Default: %(default)s'))
|
||||
|
||||
rerun.add_argument('--rerun-all',
|
||||
action=StoreTrue,
|
||||
nargs=0,
|
||||
default=False,
|
||||
help='force rerun of all tasks')
|
||||
help='Permanently delete all previous results and rerun the processing pipeline.')
|
||||
|
||||
rerun.add_argument('--rerun-from',
|
||||
action=RerunFrom,
|
||||
metavar='<string>',
|
||||
choices=processopts,
|
||||
help=('Can be one of:' + ' | '.join(processopts)))
|
||||
|
||||
# parser.add_argument('--video',
|
||||
# metavar='<string>',
|
||||
# help='Path to the video file to process')
|
||||
|
||||
# parser.add_argument('--slam-config',
|
||||
# metavar='<string>',
|
||||
# help='Path to config file for orb-slam')
|
||||
help=('Rerun processing from this stage. Can be one of: %(choices)s. Default: %(default)s'))
|
||||
|
||||
parser.add_argument('--min-num-features',
|
||||
metavar='<integer>',
|
||||
|
@ -136,8 +127,9 @@ def config(argv=None, parser=None):
|
|||
default=8000,
|
||||
type=int,
|
||||
help=('Minimum number of features to extract per image. '
|
||||
'More features leads to better results but slower '
|
||||
'execution. Default: %(default)s'))
|
||||
'More features can be useful for finding more matches between images, '
|
||||
'potentially allowing the reconstruction of areas with little overlap or insufficient features. '
|
||||
'More features also slow down processing. Default: %(default)s'))
|
||||
|
||||
parser.add_argument('--feature-type',
|
||||
metavar='<string>',
|
||||
|
@ -174,10 +166,7 @@ def config(argv=None, parser=None):
|
|||
help='Number of nearest images to pre-match based on GPS '
|
||||
'exif data. Set to 0 to skip pre-matching. '
|
||||
'Neighbors works together with Distance parameter, '
|
||||
'set both to 0 to not use pre-matching. OpenSFM '
|
||||
'uses both parameters at the same time, Bundler '
|
||||
'uses only one which has value, prefering the '
|
||||
'Neighbors parameter. Default: %(default)s')
|
||||
'set both to 0 to not use pre-matching. Default: %(default)s')
|
||||
|
||||
parser.add_argument('--matcher-distance',
|
||||
metavar='<integer>',
|
||||
|
@ -193,7 +182,7 @@ def config(argv=None, parser=None):
|
|||
action=StoreTrue,
|
||||
nargs=0,
|
||||
default=False,
|
||||
help='Turn off camera parameter optimization during bundler')
|
||||
help='Turn off camera parameter optimization during bundle adjustment. This can be sometimes useful for improving results that exhibit doming/bowling or when images are taken with a rolling shutter camera. Default: %(default)s')
|
||||
|
||||
parser.add_argument('--cameras',
|
||||
default='',
|
||||
|
@ -213,8 +202,7 @@ def config(argv=None, parser=None):
|
|||
choices=['auto', 'perspective', 'brown', 'fisheye', 'spherical'],
|
||||
help=('Set a camera projection type. Manually setting a value '
|
||||
'can help improve geometric undistortion. By default the application '
|
||||
'tries to determine a lens type from the images metadata. Can be '
|
||||
'set to one of: %(choices)s. Default: '
|
||||
'tries to determine a lens type from the images metadata. Can be one of: %(choices)s. Default: '
|
||||
'%(default)s'))
|
||||
|
||||
parser.add_argument('--radiometric-calibration',
|
||||
|
@ -227,7 +215,7 @@ def config(argv=None, parser=None):
|
|||
'to obtain reflectance values (otherwise you will get digital number values). '
|
||||
'[camera] applies black level, vignetting, row gradient gain/exposure compensation (if appropriate EXIF tags are found). '
|
||||
'[camera+sun] is experimental, applies all the corrections of [camera], plus compensates for spectral radiance registered via a downwelling light sensor (DLS) taking in consideration the angle of the sun. '
|
||||
'Can be set to one of: %(choices)s. Default: '
|
||||
'Can be one of: %(choices)s. Default: '
|
||||
'%(default)s'))
|
||||
|
||||
parser.add_argument('--max-concurrency',
|
||||
|
@ -282,25 +270,25 @@ def config(argv=None, parser=None):
|
|||
nargs=0,
|
||||
default=False,
|
||||
help='Run local bundle adjustment for every image added to the reconstruction and a global '
|
||||
'adjustment every 100 images. Speeds up reconstruction for very large datasets.')
|
||||
'adjustment every 100 images. Speeds up reconstruction for very large datasets. Default: %(default)s')
|
||||
|
||||
parser.add_argument('--use-3dmesh',
|
||||
action=StoreTrue,
|
||||
nargs=0,
|
||||
default=False,
|
||||
help='Use a full 3D mesh to compute the orthophoto instead of a 2.5D mesh. This option is a bit faster and provides similar results in planar areas.')
|
||||
help='Use a full 3D mesh to compute the orthophoto instead of a 2.5D mesh. This option is a bit faster and provides similar results in planar areas. Default: %(default)s')
|
||||
|
||||
parser.add_argument('--skip-3dmodel',
|
||||
action=StoreTrue,
|
||||
nargs=0,
|
||||
default=False,
|
||||
help='Skip generation of a full 3D model. This can save time if you only need 2D results such as orthophotos and DEMs.')
|
||||
help='Skip generation of a full 3D model. This can save time if you only need 2D results such as orthophotos and DEMs. Default: %(default)s')
|
||||
|
||||
parser.add_argument('--use-opensfm-dense',
|
||||
action=StoreTrue,
|
||||
nargs=0,
|
||||
default=False,
|
||||
help='Use opensfm to compute dense point cloud alternatively')
|
||||
help='Use OpenSfM to compute the dense point cloud instead of OpenMVS. Default: %(default)s')
|
||||
|
||||
parser.add_argument('--ignore-gsd',
|
||||
action=StoreTrue,
|
||||
|
@ -309,7 +297,7 @@ def config(argv=None, parser=None):
|
|||
help='Ignore Ground Sampling Distance (GSD). GSD '
|
||||
'caps the maximum resolution of image outputs and '
|
||||
'resizes images when necessary, resulting in faster processing and '
|
||||
'lower memory usage. Since GSD is an estimate, sometimes ignoring it can result in slightly better image output quality.')
|
||||
'lower memory usage. Since GSD is an estimate, sometimes ignoring it can result in slightly better image output quality. Default: %(default)s')
|
||||
|
||||
parser.add_argument('--mesh-size',
|
||||
metavar='<positive integer>',
|
||||
|
@ -322,39 +310,19 @@ def config(argv=None, parser=None):
|
|||
parser.add_argument('--mesh-octree-depth',
|
||||
metavar='<positive integer>',
|
||||
action=StoreValue,
|
||||
default=10,
|
||||
default=11,
|
||||
type=int,
|
||||
help=('Oct-tree depth used in the mesh reconstruction, '
|
||||
help=('Octree depth used in the mesh reconstruction, '
|
||||
'increase to get more vertices, recommended '
|
||||
'values are 8-12. Default: %(default)s'))
|
||||
|
||||
parser.add_argument('--mesh-samples',
|
||||
metavar='<float >= 1.0>',
|
||||
action=StoreValue,
|
||||
default=1.0,
|
||||
type=float,
|
||||
help=('Number of points per octree node, recommended '
|
||||
'and default value: %(default)s'))
|
||||
|
||||
parser.add_argument('--mesh-point-weight',
|
||||
metavar='<positive float>',
|
||||
action=StoreValue,
|
||||
default=4,
|
||||
type=float,
|
||||
help=('This floating point value specifies the importance'
|
||||
' that interpolation of the point samples is given in the '
|
||||
'formulation of the screened Poisson equation. The results '
|
||||
'of the original (unscreened) Poisson Reconstruction can '
|
||||
'be obtained by setting this value to 0.'
|
||||
'Default= %(default)s'))
|
||||
|
||||
parser.add_argument('--fast-orthophoto',
|
||||
action=StoreTrue,
|
||||
nargs=0,
|
||||
default=False,
|
||||
help='Skips dense reconstruction and 3D model generation. '
|
||||
'It generates an orthophoto directly from the sparse reconstruction. '
|
||||
'If you just need an orthophoto and do not need a full 3D model, turn on this option.')
|
||||
'If you just need an orthophoto and do not need a full 3D model, turn on this option. Default: %(default)s')
|
||||
|
||||
parser.add_argument('--crop',
|
||||
metavar='<positive float>',
|
||||
|
@ -388,37 +356,35 @@ def config(argv=None, parser=None):
|
|||
action=StoreTrue,
|
||||
nargs=0,
|
||||
default=False,
|
||||
help='Export the georeferenced point cloud in CSV format. Default: %(default)s')
|
||||
help='Export the georeferenced point cloud in CSV format. Default: %(default)s')
|
||||
|
||||
parser.add_argument('--pc-las',
|
||||
action=StoreTrue,
|
||||
nargs=0,
|
||||
default=False,
|
||||
help='Export the georeferenced point cloud in LAS format. Default: %(default)s')
|
||||
help='Export the georeferenced point cloud in LAS format. Default: %(default)s')
|
||||
|
||||
parser.add_argument('--pc-ept',
|
||||
action=StoreTrue,
|
||||
nargs=0,
|
||||
default=False,
|
||||
help='Export the georeferenced point cloud in Entwine Point Tile (EPT) format. Default: %(default)s')
|
||||
help='Export the georeferenced point cloud in Entwine Point Tile (EPT) format. Default: %(default)s')
|
||||
|
||||
parser.add_argument('--pc-filter',
|
||||
metavar='<positive float>',
|
||||
action=StoreValue,
|
||||
type=float,
|
||||
default=2.5,
|
||||
help='Filters the point cloud by removing points that deviate more than N standard deviations from the local mean. Set to 0 to disable filtering.'
|
||||
'\nDefault: '
|
||||
'%(default)s')
|
||||
help='Filters the point cloud by removing points that deviate more than N standard deviations from the local mean. Set to 0 to disable filtering. '
|
||||
'Default: %(default)s')
|
||||
|
||||
parser.add_argument('--pc-sample',
|
||||
metavar='<positive float>',
|
||||
action=StoreValue,
|
||||
type=float,
|
||||
default=0,
|
||||
help='Filters the point cloud by keeping only a single point around a radius N (in meters). This can be useful to limit the output resolution of the point cloud. Set to 0 to disable sampling.'
|
||||
'\nDefault: '
|
||||
'%(default)s')
|
||||
help='Filters the point cloud by keeping only a single point around a radius N (in meters). This can be useful to limit the output resolution of the point cloud. Set to 0 to disable sampling. '
|
||||
'Default: %(default)s')
|
||||
|
||||
parser.add_argument('--smrf-scalar',
|
||||
metavar='<positive float>',
|
||||
|
@ -426,8 +392,7 @@ def config(argv=None, parser=None):
|
|||
type=float,
|
||||
default=1.25,
|
||||
help='Simple Morphological Filter elevation scalar parameter. '
|
||||
'\nDefault: '
|
||||
'%(default)s')
|
||||
'Default: %(default)s')
|
||||
|
||||
parser.add_argument('--smrf-slope',
|
||||
metavar='<positive float>',
|
||||
|
@ -435,8 +400,7 @@ def config(argv=None, parser=None):
|
|||
type=float,
|
||||
default=0.15,
|
||||
help='Simple Morphological Filter slope parameter (rise over run). '
|
||||
'\nDefault: '
|
||||
'%(default)s')
|
||||
'Default: %(default)s')
|
||||
|
||||
parser.add_argument('--smrf-threshold',
|
||||
metavar='<positive float>',
|
||||
|
@ -444,8 +408,7 @@ def config(argv=None, parser=None):
|
|||
type=float,
|
||||
default=0.5,
|
||||
help='Simple Morphological Filter elevation threshold parameter (meters). '
|
||||
'\nDefault: '
|
||||
'%(default)s')
|
||||
'Default: %(default)s')
|
||||
|
||||
parser.add_argument('--smrf-window',
|
||||
metavar='<positive float>',
|
||||
|
@ -453,38 +416,33 @@ def config(argv=None, parser=None):
|
|||
type=float,
|
||||
default=18.0,
|
||||
help='Simple Morphological Filter window radius parameter (meters). '
|
||||
'\nDefault: '
|
||||
'%(default)s')
|
||||
'Default: %(default)s')
|
||||
|
||||
parser.add_argument('--texturing-data-term',
|
||||
metavar='<string>',
|
||||
action=StoreValue,
|
||||
default='gmi',
|
||||
choices=['gmi', 'area'],
|
||||
help=('Data term: [area, gmi]. Default: '
|
||||
'%(default)s'))
|
||||
help=('When texturing the 3D mesh, for each triangle, choose to prioritize images with sharp features (gmi) or those that cover the largest area (area). Default: %(default)s'))
|
||||
|
||||
parser.add_argument('--texturing-outlier-removal-type',
|
||||
metavar='<string>',
|
||||
action=StoreValue,
|
||||
default='gauss_clamping',
|
||||
choices=['none', 'gauss_clamping', 'gauss_damping'],
|
||||
help=('Type of photometric outlier removal method: '
|
||||
'[none, gauss_damping, gauss_clamping]. Default: '
|
||||
'%(default)s'))
|
||||
help=('Type of photometric outlier removal method. Can be one of: %(choices)s. Default: %(default)s'))
|
||||
|
||||
parser.add_argument('--texturing-skip-global-seam-leveling',
|
||||
action=StoreTrue,
|
||||
nargs=0,
|
||||
default=False,
|
||||
help=('Skip global seam leveling. Useful for IR data.'
|
||||
'Default: %(default)s'))
|
||||
help=('Skip normalization of colors across all images. Useful when processing radiometric data. Default: %(default)s'))
|
||||
|
||||
parser.add_argument('--texturing-skip-local-seam-leveling',
|
||||
action=StoreTrue,
|
||||
nargs=0,
|
||||
default=False,
|
||||
help='Skip local seam blending. Default: %(default)s')
|
||||
help='Skip the blending of colors near seams. Default: %(default)s')
|
||||
|
||||
parser.add_argument('--texturing-tone-mapping',
|
||||
metavar='<string>',
|
||||
|
@ -492,7 +450,7 @@ def config(argv=None, parser=None):
|
|||
choices=['none', 'gamma'],
|
||||
default='none',
|
||||
help='Turn on gamma tone mapping or none for no tone '
|
||||
'mapping. Choices are \'gamma\' or \'none\'. '
|
||||
'mapping. Can be one of %(choices)s. '
|
||||
'Default: %(default)s ')
|
||||
|
||||
parser.add_argument('--gcp',
|
||||
|
@ -500,11 +458,12 @@ def config(argv=None, parser=None):
|
|||
action=StoreValue,
|
||||
default=None,
|
||||
help=('Path to the file containing the ground control '
|
||||
'points used for georeferencing. Default: '
|
||||
'%(default)s. The file needs to '
|
||||
'points used for georeferencing. '
|
||||
'The file needs to '
|
||||
'use the following format: \n'
|
||||
'EPSG:<code> or <+proj definition>\n'
|
||||
'geo_x geo_y geo_z im_x im_y image_name [gcp_name] [extra1] [extra2]'))
|
||||
'geo_x geo_y geo_z im_x im_y image_name [gcp_name] [extra1] [extra2]\n'
|
||||
'Default: %(default)s'))
|
||||
|
||||
parser.add_argument('--geo',
|
||||
metavar='<path string>',
|
||||
|
@ -512,33 +471,32 @@ def config(argv=None, parser=None):
|
|||
default=None,
|
||||
help=('Path to the image geolocation file containing the camera center coordinates used for georeferencing. '
|
||||
'Note that omega/phi/kappa are currently not supported (you can set them to 0). '
|
||||
'Default: '
|
||||
'%(default)s. The file needs to '
|
||||
'The file needs to '
|
||||
'use the following format: \n'
|
||||
'EPSG:<code> or <+proj definition>\n'
|
||||
'image_name geo_x geo_y geo_z [omega (degrees)] [phi (degrees)] [kappa (degrees)] [horz accuracy (meters)] [vert accuracy (meters)]'
|
||||
''))
|
||||
'image_name geo_x geo_y geo_z [omega (degrees)] [phi (degrees)] [kappa (degrees)] [horz accuracy (meters)] [vert accuracy (meters)]\n'
|
||||
'Default: %(default)s'))
|
||||
|
||||
parser.add_argument('--use-exif',
|
||||
action=StoreTrue,
|
||||
nargs=0,
|
||||
default=False,
|
||||
help=('Use this tag if you have a gcp_list.txt but '
|
||||
'want to use the exif geotags instead'))
|
||||
help=('Use this tag if you have a GCP File but '
|
||||
'want to use the EXIF information for georeferencing instead. Default: %(default)s'))
|
||||
|
||||
parser.add_argument('--dtm',
|
||||
action=StoreTrue,
|
||||
nargs=0,
|
||||
default=False,
|
||||
help='Use this tag to build a DTM (Digital Terrain Model, ground only) using a simple '
|
||||
'morphological filter. Check the --dem* and --smrf* parameters for finer tuning.')
|
||||
'morphological filter. Check the --dem* and --smrf* parameters for finer tuning. Default: %(default)s')
|
||||
|
||||
parser.add_argument('--dsm',
|
||||
action=StoreTrue,
|
||||
nargs=0,
|
||||
default=False,
|
||||
help='Use this tag to build a DSM (Digital Surface Model, ground + objects) using a progressive '
|
||||
'morphological filter. Check the --dem* parameters for finer tuning.')
|
||||
'morphological filter. Check the --dem* parameters for finer tuning. Default: %(default)s')
|
||||
|
||||
parser.add_argument('--dem-gapfill-steps',
|
||||
metavar='<positive integer>',
|
||||
|
@ -549,7 +507,7 @@ def config(argv=None, parser=None):
|
|||
'Starting with a radius equal to the output resolution, N different DEMs are generated with '
|
||||
'progressively bigger radius using the inverse distance weighted (IDW) algorithm '
|
||||
'and merged together. Remaining gaps are then merged using nearest neighbor interpolation. '
|
||||
'\nDefault=%(default)s')
|
||||
'Default: %(default)s')
|
||||
|
||||
parser.add_argument('--dem-resolution',
|
||||
metavar='<float>',
|
||||
|
@ -557,7 +515,7 @@ def config(argv=None, parser=None):
|
|||
type=float,
|
||||
default=5,
|
||||
help='DSM/DTM resolution in cm / pixel. Note that this value is capped by a ground sampling distance (GSD) estimate. To remove the cap, check --ignore-gsd also.'
|
||||
'\nDefault: %(default)s')
|
||||
' Default: %(default)s')
|
||||
|
||||
parser.add_argument('--dem-decimation',
|
||||
metavar='<positive integer>',
|
||||
|
@ -565,8 +523,7 @@ def config(argv=None, parser=None):
|
|||
default=1,
|
||||
type=int,
|
||||
help='Decimate the points before generating the DEM. 1 is no decimation (full quality). '
|
||||
'100 decimates ~99%% of the points. Useful for speeding up '
|
||||
'generation.\nDefault=%(default)s')
|
||||
'100 decimates ~99%% of the points. Useful for speeding up generation of DEM results in very large datasets. Default: %(default)s')
|
||||
|
||||
parser.add_argument('--dem-euclidean-map',
|
||||
action=StoreTrue,
|
||||
|
@ -584,21 +541,21 @@ def config(argv=None, parser=None):
|
|||
action=StoreValue,
|
||||
default=5,
|
||||
type=float,
|
||||
help=('Orthophoto resolution in cm / pixel. Note that this value is capped by a ground sampling distance (GSD) estimate. To remove the cap, check --ignore-gsd also.\n'
|
||||
help=('Orthophoto resolution in cm / pixel. Note that this value is capped by a ground sampling distance (GSD) estimate. To remove the cap, check --ignore-gsd also. '
|
||||
'Default: %(default)s'))
|
||||
|
||||
parser.add_argument('--orthophoto-no-tiled',
|
||||
action=StoreTrue,
|
||||
nargs=0,
|
||||
default=False,
|
||||
help='Set this parameter if you want a stripped geoTIFF.\n'
|
||||
help='Set this parameter if you want a striped GeoTIFF. '
|
||||
'Default: %(default)s')
|
||||
|
||||
parser.add_argument('--orthophoto-png',
|
||||
action=StoreTrue,
|
||||
nargs=0,
|
||||
default=False,
|
||||
help='Set this parameter if you want to generate a PNG rendering of the orthophoto.\n'
|
||||
help='Set this parameter if you want to generate a PNG rendering of the orthophoto. '
|
||||
'Default: %(default)s')
|
||||
|
||||
parser.add_argument('--orthophoto-compression',
|
||||
|
@ -607,7 +564,7 @@ def config(argv=None, parser=None):
|
|||
type=str,
|
||||
choices=['JPEG', 'LZW', 'PACKBITS', 'DEFLATE', 'LZMA', 'NONE'],
|
||||
default='DEFLATE',
|
||||
help='Set the compression to use for orthophotos. Options: %(choices)s.\nDefault: %(default)s')
|
||||
help='Set the compression to use for orthophotos. Can be one of: %(choices)s. Default: %(default)s')
|
||||
|
||||
parser.add_argument('--orthophoto-cutline',
|
||||
action=StoreTrue,
|
||||
|
@ -631,28 +588,27 @@ def config(argv=None, parser=None):
|
|||
action=StoreTrue,
|
||||
nargs=0,
|
||||
default=False,
|
||||
help='Build orthophoto overviews using gdaladdo.')
|
||||
help='Build orthophoto overviews for faster display in programs such as QGIS. Default: %(default)s')
|
||||
|
||||
parser.add_argument('--verbose', '-v',
|
||||
action=StoreTrue,
|
||||
nargs=0,
|
||||
default=False,
|
||||
help='Print additional messages to the console\n'
|
||||
help='Print additional messages to the console. '
|
||||
'Default: %(default)s')
|
||||
|
||||
parser.add_argument('--time',
|
||||
action=StoreTrue,
|
||||
nargs=0,
|
||||
default=False,
|
||||
help='Generates a benchmark file with runtime info\n'
|
||||
help='Generates a benchmark file with runtime info. '
|
||||
'Default: %(default)s')
|
||||
|
||||
parser.add_argument('--debug',
|
||||
action=StoreTrue,
|
||||
nargs=0,
|
||||
default=False,
|
||||
help='Print debug messages\n'
|
||||
'Default: %(default)s')
|
||||
help='Print debug messages. Default: %(default)s')
|
||||
|
||||
parser.add_argument('--version',
|
||||
action='version',
|
||||
|
@ -668,7 +624,7 @@ def config(argv=None, parser=None):
|
|||
'splitting a large dataset into smaller '
|
||||
'submodels, images are grouped into clusters. '
|
||||
'This value regulates the number of images that '
|
||||
'each cluster should have on average.')
|
||||
'each cluster should have on average. Default: %(default)s')
|
||||
|
||||
parser.add_argument('--split-overlap',
|
||||
type=float,
|
||||
|
@ -679,13 +635,13 @@ def config(argv=None, parser=None):
|
|||
'After grouping images into clusters, images '
|
||||
'that are closer than this radius to a cluster '
|
||||
'are added to the cluster. This is done to ensure '
|
||||
'that neighboring submodels overlap.')
|
||||
'that neighboring submodels overlap. Default: %(default)s')
|
||||
|
||||
parser.add_argument('--split-multitracks',
|
||||
action=StoreTrue,
|
||||
nargs=0,
|
||||
default=False,
|
||||
help='Split multi-track reconstructions.')
|
||||
# parser.add_argument('--split-multitracks',
|
||||
# action=StoreTrue,
|
||||
# nargs=0,
|
||||
# default=False,
|
||||
# help='Split multi-track reconstructions.')
|
||||
|
||||
parser.add_argument('--sm-cluster',
|
||||
metavar='<string>',
|
||||
|
|
|
@ -39,8 +39,8 @@ class ODMApp:
|
|||
meshing = ODMeshingStage('odm_meshing', args, progress=60.0,
|
||||
max_vertex=args.mesh_size,
|
||||
oct_tree=args.mesh_octree_depth,
|
||||
samples=args.mesh_samples,
|
||||
point_weight=args.mesh_point_weight,
|
||||
samples=1.0,
|
||||
point_weight=4.0,
|
||||
max_concurrency=args.max_concurrency,
|
||||
verbose=args.verbose)
|
||||
texturing = ODMMvsTexStage('mvs_texturing', args, progress=70.0,
|
||||
|
|
|
@ -104,67 +104,70 @@ class ODMSplitStage(types.ODM_Stage):
|
|||
|
||||
self.update_progress(50)
|
||||
|
||||
resplit_done_file = octx.path('resplit_done.txt')
|
||||
if not io.file_exists(resplit_done_file) and bool(args.split_multitracks):
|
||||
submodels = mds.get_submodel_paths()
|
||||
i = 0
|
||||
for s in submodels:
|
||||
template = octx.path("../aligned_submodels/submodel_%04d")
|
||||
with open(s+"/reconstruction.json", "r") as f:
|
||||
j = json.load(f)
|
||||
for k in range(0, len(j)):
|
||||
v = j[k]
|
||||
path = template % i
|
||||
# TODO: this is currently not working and needs a champion to fix it
|
||||
# https://community.opendronemap.org/t/filenotfound-error-cameras-json/6047/2
|
||||
|
||||
# resplit_done_file = octx.path('resplit_done.txt')
|
||||
# if not io.file_exists(resplit_done_file) and bool(args.split_multitracks):
|
||||
# submodels = mds.get_submodel_paths()
|
||||
# i = 0
|
||||
# for s in submodels:
|
||||
# template = octx.path("../aligned_submodels/submodel_%04d")
|
||||
# with open(s+"/reconstruction.json", "r") as f:
|
||||
# j = json.load(f)
|
||||
# for k in range(0, len(j)):
|
||||
# v = j[k]
|
||||
# path = template % i
|
||||
|
||||
#Create the submodel path up to opensfm
|
||||
os.makedirs(path+"/opensfm")
|
||||
os.makedirs(path+"/images")
|
||||
# #Create the submodel path up to opensfm
|
||||
# os.makedirs(path+"/opensfm")
|
||||
# os.makedirs(path+"/images")
|
||||
|
||||
#symlinks for common data
|
||||
images = os.listdir(octx.path("../images"))
|
||||
for image in images:
|
||||
os.symlink("../../../images/"+image, path+"/images/"+image)
|
||||
os.symlink("../../../opensfm/exif", path+"/opensfm/exif")
|
||||
os.symlink("../../../opensfm/features", path+"/opensfm/features")
|
||||
os.symlink("../../../opensfm/matches", path+"/opensfm/matches")
|
||||
os.symlink("../../../opensfm/reference_lla.json", path+"/opensfm/reference_lla.json")
|
||||
os.symlink("../../../opensfm/camera_models.json", path+"/opensfm/camera_models.json")
|
||||
# #symlinks for common data
|
||||
# images = os.listdir(octx.path("../images"))
|
||||
# for image in images:
|
||||
# os.symlink("../../../images/"+image, path+"/images/"+image)
|
||||
# os.symlink("../../../opensfm/exif", path+"/opensfm/exif")
|
||||
# os.symlink("../../../opensfm/features", path+"/opensfm/features")
|
||||
# os.symlink("../../../opensfm/matches", path+"/opensfm/matches")
|
||||
# os.symlink("../../../opensfm/reference_lla.json", path+"/opensfm/reference_lla.json")
|
||||
# os.symlink("../../../opensfm/camera_models.json", path+"/opensfm/camera_models.json")
|
||||
|
||||
shutil.copy(s+"/../cameras.json", path+"/cameras.json")
|
||||
# shutil.copy(s+"/../cameras.json", path+"/cameras.json")
|
||||
|
||||
shutil.copy(s+"/../images.json", path+"/images.json")
|
||||
# shutil.copy(s+"/../images.json", path+"/images.json")
|
||||
|
||||
|
||||
with open(octx.path("config.yaml")) as f:
|
||||
doc = yaml.safe_load(f)
|
||||
# with open(octx.path("config.yaml")) as f:
|
||||
# doc = yaml.safe_load(f)
|
||||
|
||||
dmcv = "depthmap_min_consistent_views"
|
||||
if dmcv in doc:
|
||||
if len(v["shots"]) < doc[dmcv]:
|
||||
doc[dmcv] = len(v["shots"])
|
||||
print("WARNING: Reduced "+dmcv+" to accommodate short track")
|
||||
# dmcv = "depthmap_min_consistent_views"
|
||||
# if dmcv in doc:
|
||||
# if len(v["shots"]) < doc[dmcv]:
|
||||
# doc[dmcv] = len(v["shots"])
|
||||
# print("WARNING: Reduced "+dmcv+" to accommodate short track")
|
||||
|
||||
with open(path+"/opensfm/config.yaml", "w") as f:
|
||||
yaml.dump(doc, f)
|
||||
# with open(path+"/opensfm/config.yaml", "w") as f:
|
||||
# yaml.dump(doc, f)
|
||||
|
||||
#We need the original tracks file for the visualsfm export, since
|
||||
#there may still be point matches between the tracks
|
||||
shutil.copy(s+"/tracks.csv", path+"/opensfm/tracks.csv")
|
||||
# #We need the original tracks file for the visualsfm export, since
|
||||
# #there may still be point matches between the tracks
|
||||
# shutil.copy(s+"/tracks.csv", path+"/opensfm/tracks.csv")
|
||||
|
||||
#Create our new reconstruction file with only the relevant track
|
||||
with open(path+"/opensfm/reconstruction.json", "w") as o:
|
||||
json.dump([v], o)
|
||||
# #Create our new reconstruction file with only the relevant track
|
||||
# with open(path+"/opensfm/reconstruction.json", "w") as o:
|
||||
# json.dump([v], o)
|
||||
|
||||
#Create image lists
|
||||
with open(path+"/opensfm/image_list.txt", "w") as o:
|
||||
o.writelines(list(map(lambda x: "../images/"+x+'\n', v["shots"].keys())))
|
||||
with open(path+"/img_list.txt", "w") as o:
|
||||
o.writelines(list(map(lambda x: x+'\n', v["shots"].keys())))
|
||||
# #Create image lists
|
||||
# with open(path+"/opensfm/image_list.txt", "w") as o:
|
||||
# o.writelines(list(map(lambda x: "../images/"+x+'\n', v["shots"].keys())))
|
||||
# with open(path+"/img_list.txt", "w") as o:
|
||||
# o.writelines(list(map(lambda x: x+'\n', v["shots"].keys())))
|
||||
|
||||
i+=1
|
||||
os.rename(octx.path("../submodels"), octx.path("../unaligned_submodels"))
|
||||
os.rename(octx.path("../aligned_submodels"), octx.path("../submodels"))
|
||||
octx.touch(resplit_done_file)
|
||||
# i+=1
|
||||
# os.rename(octx.path("../submodels"), octx.path("../unaligned_submodels"))
|
||||
# os.rename(octx.path("../aligned_submodels"), octx.path("../submodels"))
|
||||
# octx.touch(resplit_done_file)
|
||||
|
||||
mds = metadataset.MetaDataSet(tree.opensfm)
|
||||
submodel_paths = [os.path.abspath(p) for p in mds.get_submodel_paths()]
|
||||
|
|
Ładowanie…
Reference in New Issue