2015-11-18 16:36:59 +00:00
import argparse
2019-06-25 16:22:27 +00:00
import json
2017-02-09 17:55:45 +00:00
from opendm import context
2017-03-23 18:55:22 +00:00
from opendm import io
2017-03-27 19:41:51 +00:00
from opendm import log
from appsettings import SettingsParser
2019-05-20 20:29:51 +00:00
from pyodm import Node , exceptions
2020-10-28 14:05:01 +00:00
import os
2017-03-27 19:41:51 +00:00
import sys
2015-11-18 16:36:59 +00:00
# parse arguments
2020-10-27 21:10:10 +00:00
processopts = [ ' dataset ' , ' split ' , ' merge ' , ' opensfm ' , ' openmvs ' , ' odm_filterpoints ' ,
2019-05-17 18:05:10 +00:00
' odm_meshing ' , ' mvs_texturing ' , ' odm_georeferencing ' ,
2020-05-15 18:36:46 +00:00
' odm_dem ' , ' odm_orthophoto ' , ' odm_report ' ]
2015-11-18 16:36:59 +00:00
2020-10-28 14:05:01 +00:00
with open ( os . path . join ( context . root_path , ' VERSION ' ) ) as version_file :
2017-03-23 18:55:22 +00:00
__version__ = version_file . read ( ) . strip ( )
2017-03-07 19:58:40 +00:00
2017-03-27 19:41:51 +00:00
2019-06-25 16:22:27 +00:00
def path_or_json_string ( string ) :
2019-06-28 15:10:08 +00:00
try :
return io . path_or_json_string_to_dict ( string )
except ValueError as e :
raise argparse . ArgumentTypeError ( " {0} " . format ( str ( e ) ) )
2019-06-25 16:22:27 +00:00
2019-05-05 18:32:57 +00:00
# Django URL validation regex
def url_string ( string ) :
import re
regex = re . compile (
r ' ^(?:http|ftp)s?:// ' # http:// or https://
2019-05-20 20:29:51 +00:00
r ' (?:(?:[A-Z0-9](?:[A-Z0-9-] { 0,61}[A-Z0-9])? \ .?)+(?:[A-Z] { 2,6} \ .?|[A-Z0-9-] { 2,} \ .?)| ' #domain...
2019-05-05 18:32:57 +00:00
r ' localhost| ' #localhost...
r ' \ d { 1,3} \ . \ d { 1,3} \ . \ d { 1,3} \ . \ d { 1,3}) ' # ...or ip
r ' (?:: \ d+)? ' # optional port
r ' (?:/?|[/?] \ S+)$ ' , re . IGNORECASE )
if re . match ( regex , string ) is None :
raise argparse . ArgumentTypeError ( " %s is not a valid URL. The URL must be in the format: http(s)://host[:port]/[?token=] " % string )
return string
2017-03-07 19:58:40 +00:00
2016-02-25 18:39:38 +00:00
class RerunFrom ( argparse . Action ) :
2016-02-25 19:05:45 +00:00
def __call__ ( self , parser , namespace , values , option_string = None ) :
2016-02-25 18:39:38 +00:00
setattr ( namespace , self . dest , processopts [ processopts . index ( values ) : ] )
2020-03-18 19:29:43 +00:00
setattr ( namespace , self . dest + ' _is_set ' , True )
2016-02-25 18:39:38 +00:00
2020-03-18 19:29:43 +00:00
class StoreTrue ( argparse . Action ) :
def __call__ ( self , parser , namespace , values , option_string = None ) :
setattr ( namespace , self . dest , True )
setattr ( namespace , self . dest + ' _is_set ' , True )
class StoreValue ( argparse . Action ) :
def __call__ ( self , parser , namespace , values , option_string = None ) :
setattr ( namespace , self . dest , values )
setattr ( namespace , self . dest + ' _is_set ' , True )
args = None
2016-02-25 18:39:38 +00:00
2020-09-17 17:59:44 +00:00
def config ( argv = None , parser = None ) :
2020-03-18 19:29:43 +00:00
global args
if args is not None and argv is None :
return args
2020-09-08 17:08:57 +00:00
2021-05-12 20:01:50 +00:00
if sys . platform == ' win32 ' :
usage_bin = ' run '
else :
usage_bin = ' run.sh '
2020-09-17 17:59:44 +00:00
if parser is None :
2021-05-12 20:01:50 +00:00
parser = SettingsParser ( description = ' ODM is a command line toolkit to generate maps, point clouds, 3D models and DEMs from drone, balloon or kite images. ' ,
usage = ' %s [options] <dataset name> ' % usage_bin ,
2020-09-17 17:59:44 +00:00
yaml_file = open ( context . settings_path ) )
2020-03-18 19:29:43 +00:00
2016-03-08 18:26:58 +00:00
parser . add_argument ( ' --project-path ' ,
2017-03-07 19:58:40 +00:00
metavar = ' <path> ' ,
2020-03-18 19:29:43 +00:00
action = StoreValue ,
2020-12-19 17:29:00 +00:00
help = ' Path to the project folder. Your project folder should contain subfolders for each dataset. Each dataset should have an " images " folder. ' )
2017-02-09 23:57:24 +00:00
parser . add_argument ( ' name ' ,
2021-05-12 20:01:50 +00:00
metavar = ' <dataset name> ' ,
2020-03-18 19:29:43 +00:00
action = StoreValue ,
2021-05-12 20:01:50 +00:00
type = str ,
2019-06-20 01:43:34 +00:00
default = ' code ' ,
nargs = ' ? ' ,
2020-12-19 17:29:00 +00:00
help = ' Name of dataset (i.e subfolder name within project folder). Default: %(default)s ' )
2017-02-09 23:57:24 +00:00
2017-08-24 19:19:51 +00:00
parser . add_argument ( ' --resize-to ' ,
2016-03-08 18:26:58 +00:00
metavar = ' <integer> ' ,
2020-03-18 19:29:43 +00:00
action = StoreValue ,
2017-08-24 19:19:51 +00:00
default = 2048 ,
2016-03-08 18:26:58 +00:00
type = int ,
2020-09-11 18:44:19 +00:00
help = ' Legacy option (use --feature-quality instead). Resizes images by the largest side for feature extraction purposes only. '
2019-06-18 11:21:01 +00:00
' Set to -1 to disable. This does not affect the final orthophoto '
2020-12-19 17:29:00 +00:00
' resolution quality and will not resize the original images. Default: %(default)s ' )
2016-03-08 18:26:58 +00:00
parser . add_argument ( ' --end-with ' , ' -e ' ,
metavar = ' <string> ' ,
2020-03-18 19:29:43 +00:00
action = StoreValue ,
2020-05-15 20:30:08 +00:00
default = ' odm_report ' ,
2016-03-08 18:26:58 +00:00
choices = processopts ,
2020-12-19 17:29:00 +00:00
help = ' End processing at this stage. Can be one of: %(choices)s . Default: %(default)s ' )
2016-03-08 18:26:58 +00:00
rerun = parser . add_mutually_exclusive_group ( )
rerun . add_argument ( ' --rerun ' , ' -r ' ,
metavar = ' <string> ' ,
2020-03-18 19:29:43 +00:00
action = StoreValue ,
2016-03-08 18:26:58 +00:00
choices = processopts ,
2020-12-19 17:29:00 +00:00
help = ( ' Rerun this stage only and stop. Can be one of: %(choices)s . Default: %(default)s ' ) )
2016-03-08 18:26:58 +00:00
rerun . add_argument ( ' --rerun-all ' ,
2020-03-18 19:29:43 +00:00
action = StoreTrue ,
nargs = 0 ,
2017-03-27 19:41:51 +00:00
default = False ,
2020-12-19 17:29:00 +00:00
help = ' Permanently delete all previous results and rerun the processing pipeline. ' )
2016-03-08 18:26:58 +00:00
rerun . add_argument ( ' --rerun-from ' ,
action = RerunFrom ,
metavar = ' <string> ' ,
choices = processopts ,
2020-12-19 17:29:00 +00:00
help = ( ' Rerun processing from this stage. Can be one of: %(choices)s . Default: %(default)s ' ) )
2018-01-26 19:38:26 +00:00
2016-03-08 18:26:58 +00:00
parser . add_argument ( ' --min-num-features ' ,
metavar = ' <integer> ' ,
2020-03-18 19:29:43 +00:00
action = StoreValue ,
2018-01-02 17:38:15 +00:00
default = 8000 ,
2016-03-08 18:26:58 +00:00
type = int ,
help = ( ' Minimum number of features to extract per image. '
2020-12-19 17:29:00 +00:00
' 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 ' ) )
2020-02-11 14:25:27 +00:00
parser . add_argument ( ' --feature-type ' ,
2020-03-18 19:29:43 +00:00
metavar = ' <string> ' ,
action = StoreValue ,
default = ' sift ' ,
choices = [ ' sift ' , ' hahog ' ] ,
help = ( ' Choose the algorithm for extracting keypoints and computing descriptors. '
2020-09-14 14:44:45 +00:00
' Can be one of: %(choices)s . Default: '
2020-03-18 19:29:43 +00:00
' %(default)s ' ) )
2020-09-11 18:44:19 +00:00
parser . add_argument ( ' --feature-quality ' ,
metavar = ' <string> ' ,
action = StoreValue ,
default = ' high ' ,
choices = [ ' ultra ' , ' high ' , ' medium ' , ' low ' , ' lowest ' ] ,
2020-09-11 19:26:40 +00:00
help = ( ' Set feature extraction quality. Higher quality generates better features, but requires more memory and takes longer. '
2020-09-14 14:44:45 +00:00
' Can be one of: %(choices)s . Default: '
2020-09-11 18:44:19 +00:00
' %(default)s ' ) )
2020-12-02 18:04:12 +00:00
2020-12-06 15:02:33 +00:00
parser . add_argument ( ' --matcher-type ' ,
metavar = ' <string> ' ,
action = StoreValue ,
default = ' flann ' ,
choices = [ ' flann ' , ' bow ' ] ,
help = ( ' Matcher algorithm, Fast Library for Approximate Nearest Neighbors or Bag of Words. FLANN is slower, but more stable. BOW is faster, but can sometimes miss valid matches. '
' Can be one of: %(choices)s . Default: '
' %(default)s ' ) )
2016-03-08 18:26:58 +00:00
parser . add_argument ( ' --matcher-neighbors ' ,
metavar = ' <integer> ' ,
2020-03-18 19:29:43 +00:00
action = StoreValue ,
2017-03-27 19:41:51 +00:00
default = 8 ,
2020-03-18 19:29:43 +00:00
type = int ,
2016-03-08 18:26:58 +00:00
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, '
2020-12-19 17:29:00 +00:00
' set both to 0 to not use pre-matching. Default: %(default)s ' )
2016-03-08 18:26:58 +00:00
parser . add_argument ( ' --matcher-distance ' ,
metavar = ' <integer> ' ,
2020-03-18 19:29:43 +00:00
action = StoreValue ,
2017-03-27 19:41:51 +00:00
default = 0 ,
2016-03-08 18:26:58 +00:00
type = int ,
help = ' Distance threshold in meters to find pre-matching '
2017-03-27 19:41:51 +00:00
' images based on GPS exif data. Set both '
' matcher-neighbors and this to 0 to skip '
2016-03-08 18:26:58 +00:00
' pre-matching. Default: %(default)s ' )
2017-08-01 19:00:13 +00:00
parser . add_argument ( ' --use-fixed-camera-params ' ,
2020-03-18 19:29:43 +00:00
action = StoreTrue ,
nargs = 0 ,
2017-08-01 19:00:13 +00:00
default = False ,
2020-12-19 17:29:00 +00:00
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 ' )
2017-08-01 19:00:13 +00:00
2019-06-25 16:22:27 +00:00
parser . add_argument ( ' --cameras ' ,
default = ' ' ,
2019-06-25 18:22:12 +00:00
metavar = ' <json> ' ,
2020-03-18 19:29:43 +00:00
action = StoreValue ,
2019-06-25 16:22:27 +00:00
type = path_or_json_string ,
help = ' Use the camera parameters computed from '
' another dataset instead of calculating them. '
' Can be specified either as path to a cameras.json file or as a '
' JSON string representing the contents of a '
' cameras.json file. Default: %(default)s ' )
2019-08-15 14:55:18 +00:00
2019-08-16 16:23:01 +00:00
parser . add_argument ( ' --camera-lens ' ,
2019-08-15 14:55:18 +00:00
metavar = ' <string> ' ,
2020-03-18 19:29:43 +00:00
action = StoreValue ,
2019-08-15 14:55:18 +00:00
default = ' auto ' ,
2019-08-15 21:01:11 +00:00
choices = [ ' auto ' , ' perspective ' , ' brown ' , ' fisheye ' , ' spherical ' ] ,
2019-08-15 14:55:18 +00:00
help = ( ' Set a camera projection type. Manually setting a value '
' can help improve geometric undistortion. By default the application '
2020-12-19 17:29:00 +00:00
' tries to determine a lens type from the images metadata. Can be one of: %(choices)s . Default: '
2019-08-15 14:55:18 +00:00
' %(default)s ' ) )
2019-06-25 16:22:27 +00:00
2020-02-26 22:33:08 +00:00
parser . add_argument ( ' --radiometric-calibration ' ,
metavar = ' <string> ' ,
2020-03-18 19:29:43 +00:00
action = StoreValue ,
2020-02-26 22:33:08 +00:00
default = ' none ' ,
2020-03-05 21:34:16 +00:00
choices = [ ' none ' , ' camera ' , ' camera+sun ' ] ,
2020-02-26 22:33:08 +00:00
help = ( ' Set the radiometric calibration to perform on images. '
2021-03-23 20:22:08 +00:00
' When processing multispectral and thermal images you should set this option '
' to obtain reflectance/temperature values (otherwise you will get digital number values). '
' [camera] applies black level, vignetting, row gradient gain/exposure compensation (if appropriate EXIF tags are found) and computes absolute temperature values. '
2020-03-09 20:30:15 +00:00
' [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. '
2020-12-19 17:29:00 +00:00
' Can be one of: %(choices)s . Default: '
2020-02-26 22:33:08 +00:00
' %(default)s ' ) )
2018-06-30 23:36:53 +00:00
parser . add_argument ( ' --max-concurrency ' ,
2017-01-12 17:03:14 +00:00
metavar = ' <positive integer> ' ,
2020-03-18 19:29:43 +00:00
action = StoreValue ,
2017-09-01 15:31:22 +00:00
default = context . num_cores ,
2017-01-12 17:03:14 +00:00
type = int ,
2018-06-30 23:36:53 +00:00
help = ( ' The maximum number of processes to use in various '
' processes. Peak memory requirement is ~1GB per '
' thread and 2 megapixel image resolution. Default: %(default)s ' ) )
2017-12-07 19:41:37 +00:00
2018-07-04 18:27:06 +00:00
parser . add_argument ( ' --depthmap-resolution ' ,
2018-05-16 19:41:36 +00:00
metavar = ' <positive float> ' ,
2020-03-18 19:29:43 +00:00
action = StoreValue ,
2018-05-16 19:41:36 +00:00
type = float ,
default = 640 ,
2020-11-12 15:23:02 +00:00
help = ( ' Legacy option (use --pc-quality instead). Controls the density of the point cloud by setting the resolution of the depthmap images. Higher values take longer to compute '
2018-05-16 19:41:36 +00:00
' but produce denser point clouds. '
' Default: %(default)s ' ) )
2017-12-07 19:41:37 +00:00
parser . add_argument ( ' --use-hybrid-bundle-adjustment ' ,
2020-03-18 19:29:43 +00:00
action = StoreTrue ,
nargs = 0 ,
2017-12-07 19:41:37 +00:00
default = False ,
help = ' Run local bundle adjustment for every image added to the reconstruction and a global '
2020-12-19 17:29:00 +00:00
' adjustment every 100 images. Speeds up reconstruction for very large datasets. Default: %(default)s ' )
2017-12-07 19:41:37 +00:00
2018-07-03 16:37:39 +00:00
parser . add_argument ( ' --use-3dmesh ' ,
2020-03-18 19:29:43 +00:00
action = StoreTrue ,
nargs = 0 ,
2017-04-05 17:56:48 +00:00
default = False ,
2020-12-19 17:29:00 +00:00
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 ' )
2018-07-03 16:37:39 +00:00
parser . add_argument ( ' --skip-3dmodel ' ,
2020-03-18 19:29:43 +00:00
action = StoreTrue ,
nargs = 0 ,
2018-07-03 16:37:39 +00:00
default = False ,
2020-12-19 17:29:00 +00:00
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 ' )
2021-01-15 14:59:02 +00:00
parser . add_argument ( ' --skip-report ' ,
action = StoreTrue ,
nargs = 0 ,
default = False ,
help = ' Skip generation of PDF report. This can save time if you don \' t need a report. Default: %(default)s ' )
2017-04-05 17:56:48 +00:00
2018-08-11 16:45:21 +00:00
parser . add_argument ( ' --ignore-gsd ' ,
2020-03-18 19:29:43 +00:00
action = StoreTrue ,
nargs = 0 ,
2018-08-11 16:45:21 +00:00
default = False ,
help = ' Ignore Ground Sampling Distance (GSD). GSD '
' caps the maximum resolution of image outputs and '
' resizes images when necessary, resulting in faster processing and '
2020-12-19 17:29:00 +00:00
' lower memory usage. Since GSD is an estimate, sometimes ignoring it can result in slightly better image output quality. Default: %(default)s ' )
2018-08-11 16:45:21 +00:00
2016-12-14 18:30:44 +00:00
parser . add_argument ( ' --mesh-size ' ,
2016-03-08 18:26:58 +00:00
metavar = ' <positive integer> ' ,
2020-03-18 19:29:43 +00:00
action = StoreValue ,
2019-10-22 13:52:55 +00:00
default = 200000 ,
2016-03-08 18:26:58 +00:00
type = int ,
2018-07-06 14:29:55 +00:00
help = ( ' The maximum vertex count of the output mesh. '
2016-03-08 18:26:58 +00:00
' Default: %(default)s ' ) )
2016-12-14 18:30:44 +00:00
parser . add_argument ( ' --mesh-octree-depth ' ,
2016-03-08 18:26:58 +00:00
metavar = ' <positive integer> ' ,
2020-03-18 19:29:43 +00:00
action = StoreValue ,
2020-12-19 17:29:00 +00:00
default = 11 ,
2016-03-08 18:26:58 +00:00
type = int ,
2020-12-19 17:29:00 +00:00
help = ( ' Octree depth used in the mesh reconstruction, '
2016-03-08 18:26:58 +00:00
' increase to get more vertices, recommended '
' values are 8-12. Default: %(default)s ' ) )
2018-01-01 23:48:01 +00:00
parser . add_argument ( ' --fast-orthophoto ' ,
2020-03-18 19:29:43 +00:00
action = StoreTrue ,
nargs = 0 ,
2018-01-01 23:48:01 +00:00
default = False ,
help = ' Skips dense reconstruction and 3D model generation. '
' It generates an orthophoto directly from the sparse reconstruction. '
2020-12-19 17:29:00 +00:00
' If you just need an orthophoto and do not need a full 3D model, turn on this option. Default: %(default)s ' )
2018-01-01 23:48:01 +00:00
2018-01-03 22:22:13 +00:00
parser . add_argument ( ' --crop ' ,
2018-01-04 21:54:15 +00:00
metavar = ' <positive float> ' ,
2020-03-18 19:29:43 +00:00
action = StoreValue ,
2018-01-03 22:22:13 +00:00
default = 3 ,
2018-01-04 21:54:15 +00:00
type = float ,
2018-01-03 22:22:13 +00:00
help = ( ' Automatically crop image outputs by creating a smooth buffer '
' around the dataset boundaries, shrinked by N meters. '
2018-01-03 22:27:30 +00:00
' Use 0 to disable cropping. '
2018-01-03 22:22:13 +00:00
' Default: %(default)s ' ) )
2020-11-12 15:23:02 +00:00
parser . add_argument ( ' --pc-quality ' ,
metavar = ' <string> ' ,
action = StoreValue ,
default = ' medium ' ,
2020-12-08 16:52:09 +00:00
choices = [ ' ultra ' , ' high ' , ' medium ' , ' low ' , ' lowest ' ] ,
2020-11-12 15:23:02 +00:00
help = ( ' Set point cloud quality. Higher quality generates better, denser point clouds, but requires more memory and takes longer. Each step up in quality increases processing time roughly by a factor of 4x. '
' Can be one of: %(choices)s . Default: '
' %(default)s ' ) )
2018-01-16 19:46:30 +00:00
parser . add_argument ( ' --pc-classify ' ,
2020-03-18 19:29:43 +00:00
action = StoreTrue ,
nargs = 0 ,
2019-03-05 15:50:27 +00:00
default = False ,
help = ' Classify the point cloud outputs using a Simple Morphological Filter. '
' You can control the behavior of this option by tweaking the --dem-* parameters. '
2018-01-16 19:46:30 +00:00
' Default: '
' %(default)s ' )
2018-06-04 01:01:04 +00:00
parser . add_argument ( ' --pc-csv ' ,
2020-03-18 19:29:43 +00:00
action = StoreTrue ,
nargs = 0 ,
2018-06-04 01:01:04 +00:00
default = False ,
2020-12-19 17:29:00 +00:00
help = ' Export the georeferenced point cloud in CSV format. Default: %(default)s ' )
2019-02-22 20:28:37 +00:00
parser . add_argument ( ' --pc-las ' ,
2020-03-18 19:29:43 +00:00
action = StoreTrue ,
nargs = 0 ,
2019-02-22 20:28:37 +00:00
default = False ,
2020-12-19 17:29:00 +00:00
help = ' Export the georeferenced point cloud in LAS format. Default: %(default)s ' )
2018-06-04 01:01:04 +00:00
2019-05-31 16:12:59 +00:00
parser . add_argument ( ' --pc-ept ' ,
2020-03-18 19:29:43 +00:00
action = StoreTrue ,
nargs = 0 ,
2019-05-31 16:12:59 +00:00
default = False ,
2020-12-19 17:29:00 +00:00
help = ' Export the georeferenced point cloud in Entwine Point Tile (EPT) format. Default: %(default)s ' )
2019-05-31 16:12:59 +00:00
2019-03-06 02:54:36 +00:00
parser . add_argument ( ' --pc-filter ' ,
2019-03-06 00:03:04 +00:00
metavar = ' <positive float> ' ,
2020-03-18 19:29:43 +00:00
action = StoreValue ,
2019-03-06 00:03:04 +00:00
type = float ,
default = 2.5 ,
2020-12-19 17:29:00 +00:00
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 ' )
2019-10-28 13:53:46 +00:00
parser . add_argument ( ' --pc-sample ' ,
metavar = ' <positive float> ' ,
2020-03-18 19:29:43 +00:00
action = StoreValue ,
2019-10-28 13:53:46 +00:00
type = float ,
2021-03-04 18:27:11 +00:00
default = 0 ,
2021-03-03 20:05:09 +00:00
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 and remove duplicate points. Set to 0 to disable sampling. '
2020-12-19 17:29:00 +00:00
' Default: %(default)s ' )
2018-06-04 01:01:04 +00:00
2021-03-05 14:22:27 +00:00
parser . add_argument ( ' --pc-tile ' ,
action = StoreTrue ,
nargs = 0 ,
default = False ,
help = ' Reduce the memory usage needed for depthmap fusion by splitting large scenes into tiles. Turn this on if your machine doesn \' t have much RAM and/or you \' ve set --pc-quality to high or ultra. Experimental. '
' Default: %(default)s ' )
2019-04-20 14:56:42 +00:00
parser . add_argument ( ' --smrf-scalar ' ,
metavar = ' <positive float> ' ,
2020-03-18 19:29:43 +00:00
action = StoreValue ,
2019-04-20 14:56:42 +00:00
type = float ,
default = 1.25 ,
help = ' Simple Morphological Filter elevation scalar parameter. '
2020-12-19 17:29:00 +00:00
' Default: %(default)s ' )
2019-04-20 14:56:42 +00:00
parser . add_argument ( ' --smrf-slope ' ,
metavar = ' <positive float> ' ,
2020-03-18 19:29:43 +00:00
action = StoreValue ,
2019-04-20 14:56:42 +00:00
type = float ,
default = 0.15 ,
help = ' Simple Morphological Filter slope parameter (rise over run). '
2020-12-19 17:29:00 +00:00
' Default: %(default)s ' )
2019-04-20 14:56:42 +00:00
parser . add_argument ( ' --smrf-threshold ' ,
metavar = ' <positive float> ' ,
2020-03-18 19:29:43 +00:00
action = StoreValue ,
2019-04-20 14:56:42 +00:00
type = float ,
default = 0.5 ,
help = ' Simple Morphological Filter elevation threshold parameter (meters). '
2020-12-19 17:29:00 +00:00
' Default: %(default)s ' )
2019-04-20 14:56:42 +00:00
parser . add_argument ( ' --smrf-window ' ,
metavar = ' <positive float> ' ,
2020-03-18 19:29:43 +00:00
action = StoreValue ,
2019-04-20 14:56:42 +00:00
type = float ,
default = 18.0 ,
help = ' Simple Morphological Filter window radius parameter (meters). '
2020-12-19 17:29:00 +00:00
' Default: %(default)s ' )
2019-04-20 14:56:42 +00:00
2016-12-14 18:30:44 +00:00
parser . add_argument ( ' --texturing-data-term ' ,
2016-03-08 18:26:58 +00:00
metavar = ' <string> ' ,
2020-03-18 19:29:43 +00:00
action = StoreValue ,
2017-03-27 19:41:51 +00:00
default = ' gmi ' ,
choices = [ ' gmi ' , ' area ' ] ,
2020-12-19 17:29:00 +00:00
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 ' ) )
2016-03-08 18:26:58 +00:00
2016-12-14 18:30:44 +00:00
parser . add_argument ( ' --texturing-outlier-removal-type ' ,
2016-03-08 18:26:58 +00:00
metavar = ' <string> ' ,
2020-03-18 19:29:43 +00:00
action = StoreValue ,
2017-03-27 19:41:51 +00:00
default = ' gauss_clamping ' ,
choices = [ ' none ' , ' gauss_clamping ' , ' gauss_damping ' ] ,
2020-12-19 17:29:00 +00:00
help = ( ' Type of photometric outlier removal method. Can be one of: %(choices)s . Default: %(default)s ' ) )
2016-03-08 18:26:58 +00:00
2016-12-14 18:30:44 +00:00
parser . add_argument ( ' --texturing-skip-global-seam-leveling ' ,
2020-03-18 19:29:43 +00:00
action = StoreTrue ,
nargs = 0 ,
2017-03-27 19:41:51 +00:00
default = False ,
2020-12-19 17:29:00 +00:00
help = ( ' Skip normalization of colors across all images. Useful when processing radiometric data. Default: %(default)s ' ) )
2016-03-08 18:26:58 +00:00
2016-12-14 18:30:44 +00:00
parser . add_argument ( ' --texturing-skip-local-seam-leveling ' ,
2020-03-18 19:29:43 +00:00
action = StoreTrue ,
nargs = 0 ,
2017-03-27 19:41:51 +00:00
default = False ,
2020-12-19 17:29:00 +00:00
help = ' Skip the blending of colors near seams. Default: %(default)s ' )
2016-03-08 18:26:58 +00:00
2021-03-27 21:27:13 +00:00
parser . add_argument ( ' --texturing-keep-unseen-faces ' ,
action = StoreTrue ,
nargs = 0 ,
default = False ,
help = ( ' Keep faces in the mesh that are not seen in any camera. '
' Default: %(default)s ' ) )
2017-02-22 17:41:24 +00:00
parser . add_argument ( ' --texturing-tone-mapping ' ,
metavar = ' <string> ' ,
2020-03-18 19:29:43 +00:00
action = StoreValue ,
2017-02-22 17:41:24 +00:00
choices = [ ' none ' , ' gamma ' ] ,
2017-03-27 19:41:51 +00:00
default = ' none ' ,
2017-02-22 17:41:24 +00:00
help = ' Turn on gamma tone mapping or none for no tone '
2020-12-19 17:29:00 +00:00
' mapping. Can be one of %(choices)s . '
2017-02-22 17:41:24 +00:00
' Default: %(default)s ' )
2016-12-14 18:30:44 +00:00
parser . add_argument ( ' --gcp ' ,
2016-03-08 18:26:58 +00:00
metavar = ' <path string> ' ,
2020-03-18 19:29:43 +00:00
action = StoreValue ,
2017-03-27 19:41:51 +00:00
default = None ,
2020-09-14 18:33:39 +00:00
help = ( ' Path to the file containing the ground control '
2020-12-19 17:29:00 +00:00
' points used for georeferencing. '
' The file needs to '
2020-09-14 18:33:39 +00:00
' use the following format: \n '
' EPSG:<code> or <+proj definition> \n '
2020-12-19 17:29:00 +00:00
' geo_x geo_y geo_z im_x im_y image_name [gcp_name] [extra1] [extra2] \n '
' Default: %(default)s ' ) )
2020-09-14 18:33:39 +00:00
parser . add_argument ( ' --geo ' ,
metavar = ' <path string> ' ,
action = StoreValue ,
default = None ,
2020-09-14 20:09:26 +00:00
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). '
2020-12-19 17:29:00 +00:00
' The file needs to '
2020-09-14 18:33:39 +00:00
' use the following format: \n '
' EPSG:<code> or <+proj definition> \n '
2020-12-19 17:29:00 +00:00
' image_name geo_x geo_y geo_z [omega (degrees)] [phi (degrees)] [kappa (degrees)] [horz accuracy (meters)] [vert accuracy (meters)] \n '
' Default: %(default)s ' ) )
2016-03-08 18:26:58 +00:00
2016-12-21 20:56:27 +00:00
parser . add_argument ( ' --use-exif ' ,
2020-03-18 19:29:43 +00:00
action = StoreTrue ,
nargs = 0 ,
2017-03-27 19:41:51 +00:00
default = False ,
2020-12-19 17:29:00 +00:00
help = ( ' Use this tag if you have a GCP File but '
' want to use the EXIF information for georeferencing instead. Default: %(default)s ' ) )
2016-12-21 20:56:27 +00:00
2017-06-23 15:20:46 +00:00
parser . add_argument ( ' --dtm ' ,
2020-03-18 19:29:43 +00:00
action = StoreTrue ,
nargs = 0 ,
2017-04-06 13:06:09 +00:00
default = False ,
2019-04-20 14:56:42 +00:00
help = ' Use this tag to build a DTM (Digital Terrain Model, ground only) using a simple '
2020-12-19 17:29:00 +00:00
' morphological filter. Check the --dem* and --smrf* parameters for finer tuning. Default: %(default)s ' )
2017-09-29 11:57:34 +00:00
2017-06-23 15:20:46 +00:00
parser . add_argument ( ' --dsm ' ,
2020-03-18 19:29:43 +00:00
action = StoreTrue ,
nargs = 0 ,
2017-04-06 13:06:09 +00:00
default = False ,
2017-06-23 15:20:46 +00:00
help = ' Use this tag to build a DSM (Digital Surface Model, ground + objects) using a progressive '
2020-12-19 17:29:00 +00:00
' morphological filter. Check the --dem* parameters for finer tuning. Default: %(default)s ' )
2017-04-06 13:06:09 +00:00
2017-06-23 15:20:46 +00:00
parser . add_argument ( ' --dem-gapfill-steps ' ,
metavar = ' <positive integer> ' ,
2020-03-18 19:29:43 +00:00
action = StoreValue ,
2018-07-03 00:39:36 +00:00
default = 3 ,
2017-06-23 15:20:46 +00:00
type = int ,
help = ' Number of steps used to fill areas with gaps. Set to 0 to disable gap filling. '
' 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 '
2017-06-23 19:28:46 +00:00
' and merged together. Remaining gaps are then merged using nearest neighbor interpolation. '
2020-12-19 17:29:00 +00:00
' Default: %(default)s ' )
2017-04-06 19:37:13 +00:00
parser . add_argument ( ' --dem-resolution ' ,
metavar = ' <float> ' ,
2020-03-18 19:29:43 +00:00
action = StoreValue ,
2017-04-06 19:37:13 +00:00
type = float ,
2018-08-08 13:37:51 +00:00
default = 5 ,
2020-01-22 23:05:01 +00:00
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. '
2020-12-19 17:29:00 +00:00
' Default: %(default)s ' )
2017-04-06 19:37:13 +00:00
2017-06-23 15:20:46 +00:00
parser . add_argument ( ' --dem-decimation ' ,
metavar = ' <positive integer> ' ,
2020-03-18 19:29:43 +00:00
action = StoreValue ,
2017-06-23 15:20:46 +00:00
default = 1 ,
type = int ,
help = ' Decimate the points before generating the DEM. 1 is no decimation (full quality). '
2020-12-19 17:29:00 +00:00
' 100 decimates ~99 %% of the points. Useful for speeding up generation of DEM results in very large datasets. Default: %(default)s ' )
2019-04-29 21:35:12 +00:00
parser . add_argument ( ' --dem-euclidean-map ' ,
2020-03-18 19:29:43 +00:00
action = StoreTrue ,
nargs = 0 ,
2019-04-29 21:35:12 +00:00
default = False ,
help = ' Computes an euclidean raster map for each DEM. '
' The map reports the distance from each cell to the nearest '
2019-04-30 20:09:03 +00:00
' NODATA value (before any hole filling takes place). '
' This can be useful to isolate the areas that have been filled. '
2019-04-29 21:35:12 +00:00
' Default: '
' %(default)s ' )
2017-06-23 15:20:46 +00:00
2016-12-14 18:30:44 +00:00
parser . add_argument ( ' --orthophoto-resolution ' ,
2016-03-08 18:26:58 +00:00
metavar = ' <float > 0.0> ' ,
2020-03-18 19:29:43 +00:00
action = StoreValue ,
2018-08-08 13:37:51 +00:00
default = 5 ,
2016-03-08 18:26:58 +00:00
type = float ,
2020-12-19 17:29:00 +00:00
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. '
2016-03-08 18:26:58 +00:00
' Default: %(default)s ' ) )
2017-03-10 21:09:55 +00:00
parser . add_argument ( ' --orthophoto-no-tiled ' ,
2020-03-18 19:29:43 +00:00
action = StoreTrue ,
nargs = 0 ,
2017-03-10 21:09:55 +00:00
default = False ,
2020-12-19 17:29:00 +00:00
help = ' Set this parameter if you want a striped GeoTIFF. '
2017-03-10 21:09:55 +00:00
' Default: %(default)s ' )
2019-10-24 15:48:21 +00:00
parser . add_argument ( ' --orthophoto-png ' ,
2020-03-18 19:29:43 +00:00
action = StoreTrue ,
nargs = 0 ,
2019-10-24 15:48:21 +00:00
default = False ,
2020-12-19 17:29:00 +00:00
help = ' Set this parameter if you want to generate a PNG rendering of the orthophoto. '
2019-10-24 15:48:21 +00:00
' Default: %(default)s ' )
2021-04-16 03:21:55 +00:00
parser . add_argument ( ' --orthophoto-kmz ' ,
action = StoreTrue ,
nargs = 0 ,
default = False ,
help = ' Set this parameter if you want to generate a Google Earth (KMZ) rendering of the orthophoto. '
' Default: %(default)s ' )
2017-03-10 21:09:55 +00:00
parser . add_argument ( ' --orthophoto-compression ' ,
2017-03-27 19:41:51 +00:00
metavar = ' <string> ' ,
2020-03-18 19:29:43 +00:00
action = StoreValue ,
2017-03-10 21:09:55 +00:00
type = str ,
2017-03-27 19:41:51 +00:00
choices = [ ' JPEG ' , ' LZW ' , ' PACKBITS ' , ' DEFLATE ' , ' LZMA ' , ' NONE ' ] ,
2017-03-10 21:09:55 +00:00
default = ' DEFLATE ' ,
2020-12-19 17:29:00 +00:00
help = ' Set the compression to use for orthophotos. Can be one of: %(choices)s . Default: %(default)s ' )
2019-04-29 21:35:12 +00:00
parser . add_argument ( ' --orthophoto-cutline ' ,
2020-03-18 19:29:43 +00:00
action = StoreTrue ,
nargs = 0 ,
2019-04-29 21:35:12 +00:00
default = False ,
help = ' Generates a polygon around the cropping area '
' that cuts the orthophoto around the edges of features. This polygon '
' can be useful for stitching seamless mosaics with multiple overlapping orthophotos. '
' Default: '
' %(default)s ' )
2017-03-29 20:13:34 +00:00
2020-09-17 15:28:03 +00:00
parser . add_argument ( ' --tiles ' ,
action = StoreTrue ,
nargs = 0 ,
default = False ,
help = ' Generate static tiles for orthophotos and DEMs that are '
' suitable for viewers like Leaflet or OpenLayers. '
' Default: %(default)s ' )
2017-03-31 18:53:47 +00:00
parser . add_argument ( ' --build-overviews ' ,
2020-03-18 19:29:43 +00:00
action = StoreTrue ,
nargs = 0 ,
2017-03-31 18:53:47 +00:00
default = False ,
2020-12-19 17:29:00 +00:00
help = ' Build orthophoto overviews for faster display in programs such as QGIS. Default: %(default)s ' )
2017-03-31 18:53:47 +00:00
2016-12-20 19:34:51 +00:00
parser . add_argument ( ' --verbose ' , ' -v ' ,
2020-03-18 19:29:43 +00:00
action = StoreTrue ,
nargs = 0 ,
2017-03-27 19:41:51 +00:00
default = False ,
2020-12-19 17:29:00 +00:00
help = ' Print additional messages to the console. '
2016-12-11 22:16:11 +00:00
' Default: %(default)s ' )
2016-03-08 18:26:58 +00:00
parser . add_argument ( ' --time ' ,
2020-03-18 19:29:43 +00:00
action = StoreTrue ,
nargs = 0 ,
2017-03-27 19:41:51 +00:00
default = False ,
2020-12-19 17:29:00 +00:00
help = ' Generates a benchmark file with runtime info. '
2016-03-08 18:26:58 +00:00
' Default: %(default)s ' )
2019-06-28 15:10:08 +00:00
parser . add_argument ( ' --debug ' ,
2020-03-18 19:29:43 +00:00
action = StoreTrue ,
nargs = 0 ,
2019-06-28 15:10:08 +00:00
default = False ,
2020-12-19 17:29:00 +00:00
help = ' Print debug messages. Default: %(default)s ' )
2016-03-08 18:26:58 +00:00
2017-03-10 19:36:16 +00:00
parser . add_argument ( ' --version ' ,
2017-03-23 18:55:22 +00:00
action = ' version ' ,
2020-09-14 20:09:26 +00:00
version = ' ODM {0} ' . format ( __version__ ) ,
2017-03-10 19:36:16 +00:00
help = ' Displays version number and exits. ' )
2017-03-10 16:43:26 +00:00
2019-04-23 17:59:54 +00:00
parser . add_argument ( ' --split ' ,
2019-04-23 01:42:32 +00:00
type = int ,
2020-03-18 19:29:43 +00:00
action = StoreValue ,
2019-04-23 17:59:54 +00:00
default = 999999 ,
2019-05-22 14:32:36 +00:00
metavar = ' <positive integer> ' ,
2019-04-23 01:42:32 +00:00
help = ' Average number of images per submodel. When '
' splitting a large dataset into smaller '
' submodels, images are grouped into clusters. '
' This value regulates the number of images that '
2020-12-19 17:29:00 +00:00
' each cluster should have on average. Default: %(default)s ' )
2019-04-23 01:42:32 +00:00
2019-04-23 17:59:54 +00:00
parser . add_argument ( ' --split-overlap ' ,
2019-04-23 01:42:32 +00:00
type = float ,
2020-03-18 19:29:43 +00:00
action = StoreValue ,
2019-04-23 01:42:32 +00:00
metavar = ' <positive integer> ' ,
default = 150 ,
help = ' Radius of the overlap between submodels. '
' 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 '
2020-12-19 17:29:00 +00:00
' that neighboring submodels overlap. Default: %(default)s ' )
2019-04-23 01:42:32 +00:00
2021-02-05 20:43:19 +00:00
parser . add_argument ( ' --split-image-groups ' ,
metavar = ' <path string> ' ,
action = StoreValue ,
default = None ,
help = ( ' Path to the image groups file that controls how images should be split into groups. '
' The file needs to use the following format: \n '
' image_name group_name \n '
' Default: %(default)s ' ) )
2020-12-19 17:29:00 +00:00
# parser.add_argument('--split-multitracks',
# action=StoreTrue,
# nargs=0,
# default=False,
# help='Split multi-track reconstructions.')
2020-04-27 10:31:31 +00:00
2019-05-05 18:32:57 +00:00
parser . add_argument ( ' --sm-cluster ' ,
metavar = ' <string> ' ,
2020-03-18 19:29:43 +00:00
action = StoreValue ,
2019-05-05 18:32:57 +00:00
type = url_string ,
default = None ,
2019-05-22 19:45:31 +00:00
help = ' URL to a ClusterODM instance '
2019-05-05 18:32:57 +00:00
' for distributing a split-merge workflow on '
' multiple nodes in parallel. '
' Default: %(default)s ' )
2019-04-23 01:42:32 +00:00
2019-04-30 20:09:03 +00:00
parser . add_argument ( ' --merge ' ,
metavar = ' <string> ' ,
2020-03-18 19:29:43 +00:00
action = StoreValue ,
2019-04-30 20:09:03 +00:00
default = ' all ' ,
choices = [ ' all ' , ' pointcloud ' , ' orthophoto ' , ' dem ' ] ,
help = ( ' Choose what to merge in the merge step in a split dataset. '
' By default all available outputs are merged. '
2019-06-30 16:07:21 +00:00
' Options: %(choices)s . Default: '
2019-04-30 20:09:03 +00:00
' %(default)s ' ) )
2019-08-13 17:04:38 +00:00
parser . add_argument ( ' --force-gps ' ,
2020-03-18 19:29:43 +00:00
action = StoreTrue ,
nargs = 0 ,
2019-08-13 17:04:38 +00:00
default = False ,
2019-08-13 18:35:41 +00:00
help = ( ' Use images \' GPS exif data for reconstruction, even if there are GCPs present. '
' This flag is useful if you have high precision GPS measurements. '
' If there are no GCPs, this flag does nothing. Default: %(default)s ' ) )
2020-05-01 19:25:08 +00:00
parser . add_argument ( ' --gps-accuracy ' ,
type = float ,
action = StoreValue ,
metavar = ' <positive float> ' ,
2020-10-20 20:21:29 +00:00
default = 10 ,
2020-05-01 19:25:08 +00:00
help = ' Set a value in meters for the GPS Dilution of Precision (DOP) '
' information for all images. If your images are tagged '
' with high precision GPS information (RTK), this value will be automatically '
' set accordingly. You can use this option to manually set it in case the reconstruction '
' fails. Lowering this option can sometimes help control bowling-effects over large areas. Default: %(default)s ' )
2019-08-13 17:04:38 +00:00
2020-03-30 14:32:21 +00:00
parser . add_argument ( ' --optimize-disk-space ' ,
action = StoreTrue ,
nargs = 0 ,
default = False ,
help = ( ' Delete heavy intermediate files to optimize disk space usage. This '
' affects the ability to restart the pipeline from an intermediate stage, '
' but allows datasets to be processed on machines that don \' t have sufficient '
' disk space available. Default: %(default)s ' ) )
2020-03-10 03:27:04 +00:00
parser . add_argument ( ' --pc-rectify ' ,
2020-03-18 19:29:43 +00:00
action = StoreTrue ,
nargs = 0 ,
2020-03-10 01:52:12 +00:00
default = False ,
2020-03-10 03:27:04 +00:00
help = ( ' Perform ground rectification on the point cloud. This means that wrongly classified ground '
' points will be re-classified and gaps will be filled. Useful for generating DTMs. '
2020-03-10 01:52:12 +00:00
' Default: %(default)s ' ) )
2020-12-02 18:04:12 +00:00
parser . add_argument ( ' --primary-band ' ,
metavar = ' <string> ' ,
action = StoreValue ,
default = " auto " ,
type = str ,
help = ( ' When processing multispectral datasets, you can specify the name of the primary band that will be used for reconstruction. '
' It \' s recommended to choose a band which has sharp details and is in focus. '
' Default: %(default)s ' ) )
2020-12-15 01:49:20 +00:00
parser . add_argument ( ' --skip-band-alignment ' ,
action = StoreTrue ,
nargs = 0 ,
default = False ,
2020-12-15 17:54:31 +00:00
help = ( ' When processing multispectral datasets, ODM will automatically align the images for each band. '
' If the images have been postprocessed and are already aligned, use this option. '
2020-12-15 01:49:20 +00:00
' Default: %(default)s ' ) )
2020-03-18 19:29:43 +00:00
args = parser . parse_args ( argv )
2017-03-27 19:41:51 +00:00
# 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, '
2020-09-08 17:08:57 +00:00
' or use `--project-path <path>`. Run `python3 '
2017-03-27 19:41:51 +00:00
' run.py --help` for more information. ' )
sys . exit ( 1 )
2018-01-02 17:38:15 +00:00
if args . fast_orthophoto :
2018-08-11 16:45:21 +00:00
log . ODM_INFO ( ' Fast orthophoto is turned on, automatically setting --skip-3dmodel ' )
2018-07-03 16:37:39 +00:00
args . skip_3dmodel = True
2018-01-02 17:38:15 +00:00
2020-03-10 03:27:04 +00:00
if args . pc_rectify and not args . pc_classify :
log . ODM_INFO ( " Ground rectify is turned on, automatically turning on point cloud classification " )
2020-03-10 01:52:12 +00:00
args . pc_classify = True
2019-03-05 15:50:27 +00:00
if args . dtm and not args . pc_classify :
2018-01-16 19:46:30 +00:00
log . ODM_INFO ( " DTM is turned on, automatically turning on point cloud classification " )
2019-03-05 15:50:27 +00:00
args . pc_classify = True
2018-01-16 19:46:30 +00:00
2018-07-03 16:37:39 +00:00
if args . skip_3dmodel and args . use_3dmesh :
2019-05-10 16:33:16 +00:00
log . ODM_WARNING ( ' --skip-3dmodel is set, but so is --use-3dmesh. --skip-3dmodel will be ignored. ' )
args . skip_3dmodel = False
2018-07-03 16:37:39 +00:00
2019-04-29 21:35:12 +00:00
if args . orthophoto_cutline and not args . crop :
log . ODM_WARNING ( " --orthophoto-cutline is set, but --crop is not. --crop will be set to 0.01 " )
2019-04-27 22:37:07 +00:00
args . crop = 0.01
2019-05-20 20:29:51 +00:00
if args . sm_cluster :
try :
Node . from_url ( args . sm_cluster ) . info ( )
except exceptions . NodeConnectionError as e :
log . ODM_ERROR ( " Cluster node seems to be offline: %s " % str ( e ) )
sys . exit ( 1 )
2020-03-09 15:48:24 +00:00
2020-03-09 18:34:39 +00:00
# if args.radiometric_calibration != "none" and not args.texturing_skip_global_seam_leveling:
# log.ODM_WARNING("radiometric-calibration is turned on, automatically setting --texturing-skip-global-seam-leveling")
# args.texturing_skip_global_seam_leveling = True
2020-03-09 15:48:24 +00:00
2017-03-27 19:41:51 +00:00
return args