Clean up argument parsing

Former-commit-id: 43b116842e
pull/1161/head
Dakota Benjamin 2017-03-27 15:41:51 -04:00
rodzic 58ef8bfce5
commit 2039f4479a
7 zmienionych plików z 160 dodań i 174 usunięć

4
.gitignore vendored
Wyświetl plik

@ -17,6 +17,6 @@ LAStools.zip
pcl.tar.gz
ceres-solver.tar.gz
*.pyc
pcl.tar.gz
opencv.zip
settings.yaml
settings.yaml
docker.settings.yaml

Wyświetl plik

@ -1,53 +0,0 @@
---
# A list of global configuration variables
# WARNING: DO NOT EDIT THIS FILE!!!
# Copy this file and rename to settings.yaml to override. You can also place the a settings.yaml
# file with the same format inside your project to more specific parameter needs.
# Note this only works for settings with default values. Some commands like --rerun <module>
# or --force-ccd n will have to be set in the command line (if you need to)
settings:
# These are really important to set up properly
project_path: '/home/dmb2/ODMProjects'
resize_to: 2400
start_with: 'resize'
end_with: 'odm_orthophoto'
rerun_all: False
zip_results: False
verbose: False
time: False
opensfm:
processes: 4 # IMPORTANT: Set this to nproc-1 or lower for larger datasets
min_num_features: 4000
matcher_threshold: 2.0
matcher_ratio: 0.6
matcher_neighbors: 8
matcher_distance: 0
pmvs: # The following settings only matter if use_pmvs is set to True
enabled: False
cmvs_max_images: 500
level: 1
cell_size: 2
threshold: 0.7
wsize: 7
min_images: 3
num_cores: 4 # Set this to nproc
mesh:
size: 100000
octree_depth: 9
samples: 1.0
solver_divide: 9
texturing:
data_term: 'gmi'
outlier_removal_type: 'gauss_clamping'
skip_visibility_test: False
skip_global_seam_leveling: False
skip_local_seam_leveling: False
skip_hole_filling: False
keep_unseen_faces: False
tone_mapping: 'none'
georeferencing:
gcp: !!null # YAML tag for None
use_exif: False # Set to True if you have a GCP file (it auto-detects) and want to use EXIF
orthophoto:
resolution: 20.0 # Pixels/meter

Wyświetl plik

@ -1,53 +1,49 @@
---
# A list of global configuration variables
# WARNING: DO NOT EDIT THIS FILE!!!
# Copy this file and rename to settings.yaml to override. You can also place the a settings.yaml
# file with the same format inside your project to more specific parameter needs.
# Uncomment lines as needed to edit default settings.
# Note this only works for settings with default values. Some commands like --rerun <module>
# or --force-ccd n will have to be set in the command line (if you need to)
settings:
# These are really important to set up properly
project_path: '/' # DO NOT CHANGE THIS
resize_to: 2400
start_with: 'resize'
end_with: 'odm_orthophoto'
rerun_all: False
zip_results: False
verbose: False
time: False
opensfm:
processes: 4 # IMPORTANT: Set this to nproc-1 or lower for larger datasets
min_num_features: 4000
matcher_threshold: 2.0
matcher_ratio: 0.6
matcher_neighbors: 8
matcher_distance: 0
pmvs: # The following settings only matter if use_pmvs is set to True
enabled: False
cmvs_max_images: 500
level: 1
cell_size: 2
threshold: 0.7
wsize: 7
min_images: 3
num_cores: 4 # Set this to nproc
mesh:
size: 100000
octree_depth: 9
samples: 1.0
solver_divide: 9
texturing:
data_term: 'gmi'
outlier_removal_type: 'gauss_clamping'
skip_visibility_test: False
skip_global_seam_leveling: False
skip_local_seam_leveling: False
skip_hole_filling: False
keep_unseen_faces: False
tone_mapping: 'none'
georeferencing:
gcp: !!null # YAML tag for None
use_exif: False # Set to True if you have a GCP file (it auto-detects) and want to use EXIF
orthophoto:
resolution: 20.0 # Pixels/meter
# This line is really important to set up properly
project_path: '/' #DO NOT CHANGE THIS OR DOCKER WILL NOT WORK. It should be '/'
# The rest of the settings will default to the values set unless you uncomment and change them
#resize_to: 2400
#start_with: 'resize'
#end_with: 'odm_orthophoto'
#rerun_all: False
#zip_results: False
#verbose: False
#time: False
#opensfm_processes: 4 # by default this is set to $(nproc)
#min_num_features: 4000
#matcher_threshold: 2.0
#matcher_ratio: 0.6
#matcher_neighbors: 8
#matcher_distance: 0
#use_pmvs: False # The cmvs/pmvs settings only matter if 'Enabled' is set to True
#cmvs_maximages: 500
#pmvs_level: 1
#pmvs_csize: 2
#pmvs_threshold: 0.7
#pmvs_wsize: 7
#pmvs_min_images: 3
#pmvs_num_cores: 4 # by default this is set to $(nproc)
#mesh_size: 100000
#mesh_octree_depth: 9
#mesh_samples: 1.0
#mesh_solver_divide: 9
#texturing_data_term: 'gmi'
#texturing_outlier_removal_type: 'gauss_clamping'
#texturing_skip_visibility_test: False
#texturing_skip_global_seam_leveling: False
#texturing_skip_local_seam_leveling: False
#texturing_skip_hole_filling: False
#texturing_keep_unseen_faces: False
#texturing_tone_mapping: 'none'
#gcp: !!null # YAML tag for None
#use_exif: False # Set to True if you have a GCP file (it auto-detects) and want to use EXIF
#orthophoto_resolution: 20.0 # Pixels/meter
#orthophoto_target_srs: !!null # Currently does nothing
#orthophoto_no_tiled: False
#orthophoto_compression: DEFLATE # Options are [JPEG, LZW, PACKBITS, DEFLATE, LZMA, NONE] Don't change unless you know what you are doing

Wyświetl plik

@ -1,21 +1,21 @@
import argparse
from opendm import context
from opendm import io
import yaml
from opendm import log
from yaml import safe_load
from appsettings import SettingsParser
import sys
# parse arguments
processopts = ['resize', 'opensfm', 'slam', 'cmvs', 'pmvs',
'odm_meshing', 'mvs_texturing', 'odm_georeferencing',
'odm_orthophoto']
# Load global settings file
with open(context.settings_path) as stream:
datamap = yaml.safe_load(stream)
defaultSettings = datamap['settings']
with open(io.join_paths(context.root_path, 'VERSION')) as version_file:
__version__ = version_file.read().strip()
def alphanumeric_string(string):
import re
if re.match('^[a-zA-Z0-9_-]+$', string) is None:
@ -29,8 +29,9 @@ class RerunFrom(argparse.Action):
setattr(namespace, self.dest, processopts[processopts.index(values):])
parser = argparse.ArgumentParser(description='OpenDroneMap')
parser = SettingsParser(description='OpenDroneMap',
usage='%(prog)s [options] <project name>',
yaml_file=open(context.settings_path))
def config():
parser.add_argument('--images', '-i',
@ -39,8 +40,7 @@ def config():
parser.add_argument('--project-path',
metavar='<path>',
help='Path to the project folder',
default=defaultSettings['project_path'])
help='Path to the project folder')
parser.add_argument('name',
metavar='<project name>',
@ -49,19 +49,19 @@ def config():
parser.add_argument('--resize-to', # currently doesn't support 'orig'
metavar='<integer>',
default=defaultSettings['resize_to'],
default=2400,
type=int,
help='resizes images by the largest side')
parser.add_argument('--start-with', '-s',
metavar='<string>',
default=defaultSettings['start_with'],
default='resize',
choices=processopts,
help=('Can be one of: ' + ' | '.join(processopts)))
parser.add_argument('--end-with', '-e',
metavar='<string>',
default=defaultSettings['end_with'],
default='odm_orthophoto',
choices=processopts,
help=('Can be one of:' + ' | '.join(processopts)))
@ -74,7 +74,7 @@ def config():
rerun.add_argument('--rerun-all',
action='store_true',
default=defaultSettings['rerun_all'],
default=False,
help='force rerun of all tasks')
rerun.add_argument('--rerun-from',
@ -104,7 +104,7 @@ def config():
parser.add_argument('--min-num-features',
metavar='<integer>',
default=defaultSettings['opensfm']['min_num_features'],
default=4000,
type=int,
help=('Minimum number of features to extract per image. '
'More features leads to better results but slower '
@ -112,7 +112,7 @@ def config():
parser.add_argument('--matcher-threshold',
metavar='<percent>',
default=defaultSettings['opensfm']['matcher_threshold'],
default=2.0,
type=float,
help=('Ignore matched keypoints if the two images share '
'less than <float> percent of keypoints. Default:'
@ -120,7 +120,7 @@ def config():
parser.add_argument('--matcher-ratio',
metavar='<float>',
default=defaultSettings['opensfm']['matcher_ratio'],
default=0.6,
type=float,
help=('Ratio of the distance to the next best matched '
'keypoint. Default: %(default)s'))
@ -128,7 +128,7 @@ def config():
parser.add_argument('--matcher-neighbors',
type=int,
metavar='<integer>',
default=defaultSettings['opensfm']['matcher_neighbors'],
default=8,
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, '
@ -139,34 +139,35 @@ def config():
parser.add_argument('--matcher-distance',
metavar='<integer>',
default=defaultSettings['opensfm']['matcher_distance'],
default=0,
type=int,
help='Distance threshold in meters to find pre-matching '
'images based on GPS exif data. Set to 0 to skip '
'images based on GPS exif data. Set both '
'matcher-neighbors and this to 0 to skip '
'pre-matching. Default: %(default)s')
parser.add_argument('--opensfm-processes',
metavar='<positive integer>',
default=defaultSettings['opensfm']['processes'],
default=context.num_cores,
type=int,
help=('The maximum number of processes to use in dense '
'reconstruction. Default: %(default)s'))
parser.add_argument('--use-pmvs',
action='store_true',
default=defaultSettings['pmvs']['enabled'],
default=False,
help='Use pmvs to compute point cloud alternatively')
parser.add_argument('--cmvs-maxImages',
metavar='<integer>',
default=defaultSettings['pmvs']['cmvs_max_images'],
default=500,
type=int,
help='The maximum number of images per cluster. '
'Default: %(default)s')
parser.add_argument('--pmvs-level',
metavar='<positive integer>',
default=defaultSettings['pmvs']['level'],
default=1,
type=int,
help=('The level in the image pyramid that is used '
'for the computation. see '
@ -175,14 +176,14 @@ def config():
parser.add_argument('--pmvs-csize',
metavar='<positive integer>',
default=defaultSettings['pmvs']['cell_size'],
default=2,
type=int,
help='Cell size controls the density of reconstructions'
'Default: %(default)s')
parser.add_argument('--pmvs-threshold',
metavar='<float: -1.0 <= x <= 1.0>',
default=defaultSettings['pmvs']['threshold'],
default=0.7,
type=float,
help=('A patch reconstruction is accepted as a success '
'and kept if its associated photometric consistency '
@ -190,7 +191,7 @@ def config():
parser.add_argument('--pmvs-wsize',
metavar='<positive integer>',
default=defaultSettings['pmvs']['wsize'],
default=7,
type=int,
help='pmvs samples wsize x wsize pixel colors from '
'each image to compute photometric consistency '
@ -201,7 +202,7 @@ def config():
parser.add_argument('--pmvs-min-images',
metavar='<positive integer>',
default=defaultSettings['pmvs']['min_images'],
default=3,
type=int,
help=('Each 3D point must be visible in at least '
'minImageNum images for being reconstructed. 3 is '
@ -209,21 +210,21 @@ def config():
parser.add_argument('--pmvs-num-cores',
metavar='<positive integer>',
default=defaultSettings['pmvs']['num_cores'],
default=context.num_cores,
type=int,
help=('The maximum number of cores to use in dense '
'reconstruction. Default: %(default)s'))
parser.add_argument('--mesh-size',
metavar='<positive integer>',
default=defaultSettings['mesh']['size'],
default=100000,
type=int,
help=('The maximum vertex count of the output mesh '
'Default: %(default)s'))
parser.add_argument('--mesh-octree-depth',
metavar='<positive integer>',
default=defaultSettings['mesh']['octree_depth'],
default=9,
type=int,
help=('Oct-tree depth used in the mesh reconstruction, '
'increase to get more vertices, recommended '
@ -231,14 +232,14 @@ def config():
parser.add_argument('--mesh-samples',
metavar='<float >= 1.0>',
default=defaultSettings['mesh']['samples'],
default=1.0,
type=float,
help=('Number of points per octree node, recommended '
'and default value: %(default)s'))
parser.add_argument('--mesh-solver-divide',
metavar='<positive integer>',
default=defaultSettings['mesh']['solver_divide'],
default=9,
type=int,
help=('Oct-tree depth at which the Laplacian equation '
'is solved in the surface reconstruction step. '
@ -248,57 +249,59 @@ def config():
parser.add_argument('--texturing-data-term',
metavar='<string>',
default=defaultSettings['texturing']['data_term'],
default='gmi',
choices=['gmi', 'area'],
help=('Data term: [area, gmi]. Default: '
'%(default)s'))
parser.add_argument('--texturing-outlier-removal-type',
metavar='<string>',
default=defaultSettings['texturing']['outlier_removal_type'],
default='gauss_clamping',
choices=['none', 'gauss_clamping', 'gauss_damping'],
help=('Type of photometric outlier removal method: '
'[none, gauss_damping, gauss_clamping]. Default: '
'%(default)s'))
parser.add_argument('--texturing-skip-visibility-test',
action='store_true',
default=defaultSettings['texturing']['skip_visibility_test'],
default=False,
help=('Skip geometric visibility test. Default: '
' %(default)s'))
parser.add_argument('--texturing-skip-global-seam-leveling',
action='store_true',
default=defaultSettings['texturing']['skip_global_seam_leveling'],
default=False,
help=('Skip global seam leveling. Useful for IR data.'
'Default: %(default)s'))
parser.add_argument('--texturing-skip-local-seam-leveling',
action='store_true',
default=defaultSettings['texturing']['skip_local_seam_leveling'],
default=False,
help='Skip local seam blending. Default: %(default)s')
parser.add_argument('--texturing-skip-hole-filling',
action='store_true',
default=defaultSettings['texturing']['skip_hole_filling'],
default=False,
help=('Skip filling of holes in the mesh. Default: '
' %(default)s'))
parser.add_argument('--texturing-keep-unseen-faces',
action='store_true',
default=defaultSettings['texturing']['keep_unseen_faces'],
default=False,
help=('Keep faces in the mesh that are not seen in any camera. '
'Default: %(default)s'))
parser.add_argument('--texturing-tone-mapping',
metavar='<string>',
choices=['none', 'gamma'],
default=defaultSettings['texturing']['tone_mapping'],
default='none',
help='Turn on gamma tone mapping or none for no tone '
'mapping. Choices are \'gamma\' or \'none\'. '
'Default: %(default)s ')
parser.add_argument('--gcp',
metavar='<path string>',
default=defaultSettings['georeferencing']['gcp'],
default=None,
help=('path to the file containing the ground control '
'points used for georeferencing. Default: '
'%(default)s. The file needs to '
@ -307,13 +310,13 @@ def config():
parser.add_argument('--use-exif',
action='store_true',
default=defaultSettings['georeferencing']['use_exif'],
default=False,
help=('Use this tag if you have a gcp_list.txt but '
'want to use the exif geotags instead'))
parser.add_argument('--orthophoto-resolution',
metavar='<float > 0.0>',
default=defaultSettings['orthophoto']['resolution'],
default=20.0,
type=float,
help=('Orthophoto ground resolution in pixels/meter'
'Default: %(default)s'))
@ -333,9 +336,9 @@ def config():
'Default: %(default)s')
parser.add_argument('--orthophoto-compression',
metavar='<STRING>',
metavar='<string>',
type=str,
choices=['JPEG','LZW','PACKBITS','DEFLATE','LZMA','NONE'],
choices=['JPEG', 'LZW', 'PACKBITS', 'DEFLATE', 'LZMA', 'NONE'],
default='DEFLATE',
help='Set the compression to use. Note that this could '
'break gdal_translate if you don\'t know what you '
@ -343,18 +346,18 @@ def config():
parser.add_argument('--zip-results',
action='store_true',
default=defaultSettings['zip_results'],
default=False,
help='compress the results using gunzip')
parser.add_argument('--verbose', '-v',
action='store_true',
default=defaultSettings['verbose'],
default=False,
help='Print additional messages to the console\n'
'Default: %(default)s')
parser.add_argument('--time',
action='store_true',
default=defaultSettings['time'],
default=False,
help='Generates a benchmark file with runtime info\n'
'Default: %(default)s')
@ -363,4 +366,14 @@ def config():
version='OpenDroneMap {0}'.format(__version__),
help='Displays version number and exits. ')
return parser.parse_args()
args = parser.parse_args()
# check that the project path setting has been set properly
if not args.project_path:
log.ODM_ERROR('You need to set the project path in the '
'settings.yaml file before you can run ODM, '
'or use `--project-path <path>`. Run `python '
'run.py --help` for more information. ')
sys.exit(1)
return args

Wyświetl plik

@ -39,9 +39,6 @@ odm_modules_path = os.path.join(root_path, "build/bin")
odm_modules_src_path = os.path.join(root_path, "modules")
settings_path = os.path.join(root_path, 'settings.yaml')
if not io.file_exists(settings_path):
settings_path = os.path.join(root_path, 'default.settings.yaml')
# Define supported image extensions
supported_extensions = {'.jpg','.jpeg','.png'}

20
run.py
Wyświetl plik

@ -4,41 +4,25 @@ from opendm import log
from opendm import config
from opendm import system
from opendm import io
from opendm import context
import sys
import ecto
import os
from scripts.odm_app import ODMApp
def usage():
log.ODM_ERROR('You must specify a project name:')
log.ODM_ERROR('USAGE: %s [project name]' % sys.argv[0])
log.ODM_ERROR('OpenDroneMap app finished - %s' % system.now())
sys.exit(0)
if __name__ == '__main__':
args = config.config()
#if args.version:
# log.ODM_INFO(__version__)
# sys.exit(0)
log.ODM_INFO('Initializing OpenDroneMap app - %s' % system.now())
# Force to provide the images path
if args.project_path is None:
usage()
# Add project dir if doesn't exist
args.project_path = io.join_paths(args.project_path, args.name)
if not io.dir_exists(args.project_path):
log.ODM_WARNING('Directory %s does not exist. Creating it now.' % args.name)
system.mkdir_p(os.path.abspath(args.project_path))
#If user asks to rerun everything, delete all of the existing progress directories.
# If user asks to rerun everything, delete all of the existing progress directories.
# TODO: Move this somewhere it's not hard-coded
if args.rerun_all:
os.system("rm -rf "

49
settings.yaml 100644
Wyświetl plik

@ -0,0 +1,49 @@
---
# A list of global configuration variables
# Uncomment lines as needed to edit default settings.
# Note this only works for settings with default values. Some commands like --rerun <module>
# or --force-ccd n will have to be set in the command line (if you need to)
# This line is really important to set up properly
project_path: '' # Example: '/home/user/ODMProjects
# The rest of the settings will default to the values set unless you uncomment and change them
#resize_to: 2400
#start_with: 'resize'
#end_with: 'odm_orthophoto'
#rerun_all: False
#zip_results: False
#verbose: False
#time: False
#opensfm_processes: 4 # by default this is set to $(nproc)
#min_num_features: 4000
#matcher_threshold: 2.0
#matcher_ratio: 0.6
#matcher_neighbors: 8
#matcher_distance: 0
#use_pmvs: False # The cmvs/pmvs settings only matter if 'Enabled' is set to True
#cmvs_maximages: 500
#pmvs_level: 1
#pmvs_csize: 2
#pmvs_threshold: 0.7
#pmvs_wsize: 7
#pmvs_min_images: 3
#pmvs_num_cores: 4 # by default this is set to $(nproc)
#mesh_size: 100000
#mesh_octree_depth: 9
#mesh_samples: 1.0
#mesh_solver_divide: 9
#texturing_data_term: 'gmi'
#texturing_outlier_removal_type: 'gauss_clamping'
#texturing_skip_visibility_test: False
#texturing_skip_global_seam_leveling: False
#texturing_skip_local_seam_leveling: False
#texturing_skip_hole_filling: False
#texturing_keep_unseen_faces: False
#texturing_tone_mapping: 'none'
#gcp: !!null # YAML tag for None
#use_exif: False # Set to True if you have a GCP file (it auto-detects) and want to use EXIF
#orthophoto_resolution: 20.0 # Pixels/meter
#orthophoto_target_srs: !!null # Currently does nothing
#orthophoto_no_tiled: False
#orthophoto_compression: DEFLATE # Options are [JPEG, LZW, PACKBITS, DEFLATE, LZMA, NONE] Don't change unless you know what you are doing