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
2017-03-27 19:41:51 +00:00
import sys
2015-11-18 16:36:59 +00:00
# parse arguments
2019-05-17 18:05:10 +00:00
processopts = [ ' dataset ' , ' split ' , ' merge ' , ' opensfm ' , ' mve ' , ' odm_filterpoints ' ,
' odm_meshing ' , ' mvs_texturing ' , ' odm_georeferencing ' ,
2017-06-23 15:20:46 +00:00
' odm_dem ' , ' odm_orthophoto ' ]
2015-11-18 16:36:59 +00:00
2017-03-23 18:55:22 +00:00
with open ( io . join_paths ( context . root_path , ' VERSION ' ) ) as version_file :
__version__ = version_file . read ( ) . strip ( )
2017-03-07 19:58:40 +00:00
2017-03-27 19:41:51 +00:00
2017-02-09 23:57:24 +00:00
def alphanumeric_string ( string ) :
import re
2017-03-08 20:19:00 +00:00
if re . match ( ' ^[a-zA-Z0-9_-]+$ ' , string ) is None :
2017-02-09 23:57:24 +00:00
msg = ' {0} is not a valid name. Must use alphanumeric characters. ' . format ( string )
raise argparse . ArgumentTypeError ( msg )
return string
2016-02-26 18:50:12 +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 ) : ] )
2017-03-27 19:41:51 +00:00
parser = SettingsParser ( description = ' OpenDroneMap ' ,
usage = ' %(prog)s [options] <project name> ' ,
yaml_file = open ( context . settings_path ) )
2016-03-08 18:26:58 +00:00
def config ( ) :
parser . add_argument ( ' --project-path ' ,
2017-03-07 19:58:40 +00:00
metavar = ' <path> ' ,
2017-03-27 19:41:51 +00:00
help = ' Path to the project folder ' )
2016-03-08 18:26:58 +00:00
2017-02-09 23:57:24 +00:00
parser . add_argument ( ' name ' ,
2017-03-07 19:58:40 +00:00
metavar = ' <project name> ' ,
2017-02-09 23:57:24 +00:00
type = alphanumeric_string ,
2019-06-20 01:43:34 +00:00
default = ' code ' ,
nargs = ' ? ' ,
2017-02-09 23:57:24 +00:00
help = ' Name of Project (i.e subdirectory of projects folder) ' )
2017-08-24 19:19:51 +00:00
parser . add_argument ( ' --resize-to ' ,
2016-03-08 18:26:58 +00:00
metavar = ' <integer> ' ,
2017-08-24 19:19:51 +00:00
default = 2048 ,
2016-03-08 18:26:58 +00:00
type = int ,
2019-08-15 21:01:11 +00:00
help = ' 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 '
2019-08-15 21:01:11 +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> ' ,
2017-03-27 19:41:51 +00:00
default = ' odm_orthophoto ' ,
2016-03-08 18:26:58 +00:00
choices = processopts ,
help = ( ' Can be one of: ' + ' | ' . join ( processopts ) ) )
rerun = parser . add_mutually_exclusive_group ( )
rerun . add_argument ( ' --rerun ' , ' -r ' ,
metavar = ' <string> ' ,
choices = processopts ,
help = ( ' Can be one of: ' + ' | ' . join ( processopts ) ) )
rerun . add_argument ( ' --rerun-all ' ,
action = ' store_true ' ,
2017-03-27 19:41:51 +00:00
default = False ,
2016-03-08 18:26:58 +00:00
help = ' force rerun of all tasks ' )
rerun . add_argument ( ' --rerun-from ' ,
action = RerunFrom ,
metavar = ' <string> ' ,
choices = processopts ,
help = ( ' Can be one of: ' + ' | ' . join ( processopts ) ) )
2019-06-21 17:14:44 +00:00
# parser.add_argument('--video',
# metavar='<string>',
# help='Path to the video file to process')
2016-05-18 11:09:36 +00:00
2019-06-21 17:14:44 +00:00
# parser.add_argument('--slam-config',
# metavar='<string>',
# help='Path to config file for orb-slam')
2018-01-26 19:38:26 +00:00
2016-03-08 18:26:58 +00:00
parser . add_argument ( ' --min-num-features ' ,
metavar = ' <integer> ' ,
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. '
' More features leads to better results but slower '
' execution. Default: %(default)s ' ) )
parser . add_argument ( ' --matcher-neighbors ' ,
type = int ,
metavar = ' <integer> ' ,
2017-03-27 19:41:51 +00:00
default = 8 ,
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, '
' 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 ' )
parser . add_argument ( ' --matcher-distance ' ,
metavar = ' <integer> ' ,
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 ' ,
action = ' store_true ' ,
default = False ,
help = ' Turn off camera parameter optimization during bundler ' )
2019-06-25 16:22:27 +00:00
parser . add_argument ( ' --cameras ' ,
default = ' ' ,
2019-06-25 18:22:12 +00:00
metavar = ' <json> ' ,
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> ' ,
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 '
2019-08-16 16:23:01 +00:00
' tries to determine a lens type from the images metadata. Can be '
2019-08-15 21:01:11 +00:00
' set to one of: [auto, perspective, brown, fisheye, spherical]. Default: '
2019-08-15 14:55:18 +00:00
' %(default)s ' ) )
2019-06-25 16:22:27 +00:00
2018-06-30 23:36:53 +00:00
parser . add_argument ( ' --max-concurrency ' ,
2017-01-12 17:03:14 +00:00
metavar = ' <positive integer> ' ,
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> ' ,
type = float ,
default = 640 ,
2018-07-04 18:27:06 +00:00
help = ( ' 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 ' ) )
parser . add_argument ( ' --opensfm-depthmap-min-consistent-views ' ,
metavar = ' <integer: 2 <= x <= 9> ' ,
type = int ,
default = 3 ,
help = ( ' Minimum number of views that should reconstruct a point for it to be valid. Use lower values '
2018-05-16 22:11:44 +00:00
' if your images have less overlap. Lower values result in denser point clouds '
2018-05-16 19:41:36 +00:00
' but with more noise. '
' Default: %(default)s ' ) )
parser . add_argument ( ' --opensfm-depthmap-method ' ,
metavar = ' <string> ' ,
2018-05-18 20:53:49 +00:00
default = ' PATCH_MATCH ' ,
choices = [ ' PATCH_MATCH ' , ' BRUTE_FORCE ' , ' PATCH_MATCH_SAMPLE ' ] ,
2018-05-16 19:41:36 +00:00
help = ( ' Raw depthmap computation algorithm. '
2018-05-18 20:53:49 +00:00
' PATCH_MATCH and PATCH_MATCH_SAMPLE are faster, but might miss some valid points. '
2018-05-16 19:41:36 +00:00
' BRUTE_FORCE takes longer but produces denser reconstructions. '
' Default: %(default)s ' ) )
parser . add_argument ( ' --opensfm-depthmap-min-patch-sd ' ,
metavar = ' <positive float> ' ,
type = float ,
default = 1 ,
2018-05-18 20:53:49 +00:00
help = ( ' When using PATCH_MATCH or PATCH_MATCH_SAMPLE, controls the standard deviation threshold to include patches. '
2018-05-16 19:41:36 +00:00
' Patches with lower standard deviation are ignored. '
' Default: %(default)s ' ) )
2017-12-07 19:41:37 +00:00
parser . add_argument ( ' --use-hybrid-bundle-adjustment ' ,
action = ' store_true ' ,
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. ' )
2019-04-03 20:23:21 +00:00
parser . add_argument ( ' --mve-confidence ' ,
metavar = ' <float: 0 <= x <= 1> ' ,
type = float ,
2019-04-11 01:08:05 +00:00
default = 0.60 ,
2019-04-03 20:23:21 +00:00
help = ( ' Discard points that have less than a certain confidence threshold. '
' This only affects dense reconstructions performed with MVE. '
' Higher values discard more points. '
' Default: %(default)s ' ) )
2018-07-03 16:37:39 +00:00
parser . add_argument ( ' --use-3dmesh ' ,
2017-04-05 17:56:48 +00:00
action = ' store_true ' ,
default = False ,
2018-07-03 16:37:39 +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. ' )
parser . add_argument ( ' --skip-3dmodel ' ,
action = ' store_true ' ,
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. ' )
2017-04-05 17:56:48 +00:00
2018-06-27 18:32:49 +00:00
parser . add_argument ( ' --use-opensfm-dense ' ,
2016-09-30 13:08:56 +00:00
action = ' store_true ' ,
2017-03-27 19:41:51 +00:00
default = False ,
2018-06-27 18:32:49 +00:00
help = ' Use opensfm to compute dense point cloud alternatively ' )
2018-08-11 16:45:21 +00:00
parser . add_argument ( ' --ignore-gsd ' ,
action = ' store_true ' ,
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 '
' lower memory usage. Since GSD is an estimate, sometimes ignoring it can result in slightly better image output quality. ' )
2016-12-14 18:30:44 +00:00
parser . add_argument ( ' --mesh-size ' ,
2016-03-08 18:26:58 +00:00
metavar = ' <positive integer> ' ,
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> ' ,
2019-10-22 13:52:55 +00:00
default = 11 ,
2016-03-08 18:26:58 +00:00
type = int ,
help = ( ' Oct-tree depth used in the mesh reconstruction, '
' increase to get more vertices, recommended '
' values are 8-12. Default: %(default)s ' ) )
2016-12-14 18:30:44 +00:00
parser . add_argument ( ' --mesh-samples ' ,
2016-03-08 18:26:58 +00:00
metavar = ' <float >= 1.0> ' ,
2018-07-07 16:50:25 +00:00
default = 1.0 ,
2016-03-08 18:26:58 +00:00
type = float ,
help = ( ' Number of points per octree node, recommended '
' and default value: %(default)s ' ) )
2018-07-05 23:02:00 +00:00
parser . add_argument ( ' --mesh-point-weight ' ,
2019-04-20 14:56:42 +00:00
metavar = ' <positive float> ' ,
2018-07-05 23:02:00 +00:00
default = 4 ,
2018-01-04 21:54:15 +00:00
type = float ,
2018-07-05 23:02:00 +00:00
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 ' ) )
2017-04-06 21:33:36 +00:00
2018-01-01 23:48:01 +00:00
parser . add_argument ( ' --fast-orthophoto ' ,
action = ' store_true ' ,
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. '
' Experimental. ' )
2018-01-03 22:22:13 +00:00
parser . add_argument ( ' --crop ' ,
2018-01-04 21:54:15 +00:00
metavar = ' <positive float> ' ,
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 ' ) )
2018-01-16 19:46:30 +00:00
parser . add_argument ( ' --pc-classify ' ,
2019-03-05 15:50:27 +00:00
action = ' store_true ' ,
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 ' ,
action = ' store_true ' ,
default = False ,
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 ' ,
action = ' store_true ' ,
default = False ,
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 ' ,
action = ' store_true ' ,
default = False ,
help = ' Export the georeferenced point cloud in Entwine Point Tile (EPT) format. Default: %(default)s ' )
2019-03-06 02:54:36 +00:00
parser . add_argument ( ' --pc-filter ' ,
2019-03-06 00:03:04 +00:00
metavar = ' <positive float> ' ,
type = float ,
default = 2.5 ,
2019-03-06 02:54:36 +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. '
2019-03-06 00:03:04 +00:00
' \n Default: '
' %(default)s ' )
2019-10-28 13:53:46 +00:00
parser . add_argument ( ' --pc-sample ' ,
metavar = ' <positive float> ' ,
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. '
' \n Default: '
' %(default)s ' )
2018-06-04 01:01:04 +00:00
2019-04-20 14:56:42 +00:00
parser . add_argument ( ' --smrf-scalar ' ,
metavar = ' <positive float> ' ,
type = float ,
default = 1.25 ,
help = ' Simple Morphological Filter elevation scalar parameter. '
' \n Default: '
' %(default)s ' )
parser . add_argument ( ' --smrf-slope ' ,
metavar = ' <positive float> ' ,
type = float ,
default = 0.15 ,
help = ' Simple Morphological Filter slope parameter (rise over run). '
' \n Default: '
' %(default)s ' )
parser . add_argument ( ' --smrf-threshold ' ,
metavar = ' <positive float> ' ,
type = float ,
default = 0.5 ,
help = ' Simple Morphological Filter elevation threshold parameter (meters). '
' \n Default: '
' %(default)s ' )
parser . add_argument ( ' --smrf-window ' ,
metavar = ' <positive float> ' ,
type = float ,
default = 18.0 ,
help = ' Simple Morphological Filter window radius parameter (meters). '
' \n Default: '
' %(default)s ' )
2016-12-14 18:30:44 +00:00
parser . add_argument ( ' --texturing-data-term ' ,
2016-03-08 18:26:58 +00:00
metavar = ' <string> ' ,
2017-03-27 19:41:51 +00:00
default = ' gmi ' ,
choices = [ ' gmi ' , ' area ' ] ,
2016-12-14 18:30:44 +00:00
help = ( ' Data term: [area, gmi]. Default: '
' %(default)s ' ) )
2016-03-08 18:26:58 +00:00
2018-07-08 04:16:45 +00:00
parser . add_argument ( ' --texturing-nadir-weight ' ,
metavar = ' <integer: 0 <= x <= 32> ' ,
default = 16 ,
type = int ,
help = ( ' Affects orthophotos only. '
' Higher values result in sharper corners, but can affect color distribution and blurriness. '
' Use lower values for planar areas and higher values for urban areas. '
' The default value works well for most scenarios. Default: '
' %(default)s ' ) )
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> ' ,
2017-03-27 19:41:51 +00:00
default = ' gauss_clamping ' ,
choices = [ ' none ' , ' gauss_clamping ' , ' gauss_damping ' ] ,
2017-09-29 11:57:34 +00:00
help = ( ' Type of photometric outlier removal method: '
' [none, gauss_damping, gauss_clamping]. Default: '
2016-03-08 18:26:58 +00:00
' %(default)s ' ) )
2016-12-14 18:30:44 +00:00
parser . add_argument ( ' --texturing-skip-visibility-test ' ,
2016-09-24 15:14:01 +00:00
action = ' store_true ' ,
2017-03-27 19:41:51 +00:00
default = False ,
2016-12-14 18:30:44 +00:00
help = ( ' Skip geometric visibility test. 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 ' ,
2016-09-24 15:14:01 +00:00
action = ' store_true ' ,
2017-03-27 19:41:51 +00:00
default = False ,
2016-12-14 18:30:44 +00:00
help = ( ' Skip global seam leveling. Useful for IR 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 ' ,
2016-09-24 15:14:01 +00:00
action = ' store_true ' ,
2017-03-27 19:41:51 +00:00
default = False ,
2016-12-14 18:30:44 +00:00
help = ' Skip local seam blending. Default: %(default)s ' )
2016-03-08 18:26:58 +00:00
2016-12-14 18:30:44 +00:00
parser . add_argument ( ' --texturing-skip-hole-filling ' ,
2016-09-24 15:14:01 +00:00
action = ' store_true ' ,
2017-03-27 19:41:51 +00:00
default = False ,
2016-12-14 18:30:44 +00:00
help = ( ' Skip filling of holes in the mesh. Default: '
' %(default)s ' ) )
2016-03-08 18:26:58 +00:00
2016-12-14 18:30:44 +00:00
parser . add_argument ( ' --texturing-keep-unseen-faces ' ,
2016-09-24 15:14:01 +00:00
action = ' store_true ' ,
2017-03-27 19:41:51 +00:00
default = False ,
2017-09-29 11:57:34 +00:00
help = ( ' Keep faces in the mesh that are not seen in any camera. '
2016-03-08 18:26:58 +00:00
' Default: %(default)s ' ) )
2017-02-22 17:41:24 +00:00
parser . add_argument ( ' --texturing-tone-mapping ' ,
metavar = ' <string> ' ,
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 '
' mapping. Choices are \' gamma \' or \' none \' . '
' 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> ' ,
2017-03-27 19:41:51 +00:00
default = None ,
2016-03-08 18:26:58 +00:00
help = ( ' path to the file containing the ground control '
' points used for georeferencing. Default: '
' %(default)s . The file needs to '
' be on the following line format: \n easting '
' northing height pixelrow pixelcol imagename ' ) )
2016-12-21 20:56:27 +00:00
parser . add_argument ( ' --use-exif ' ,
action = ' store_true ' ,
2017-03-27 19:41:51 +00:00
default = False ,
2016-12-21 20:56:27 +00:00
help = ( ' Use this tag if you have a gcp_list.txt but '
' want to use the exif geotags instead ' ) )
2017-06-23 15:20:46 +00:00
parser . add_argument ( ' --dtm ' ,
2017-04-06 13:06:09 +00:00
action = ' store_true ' ,
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 '
' morphological filter. Check the --dem* and --smrf* parameters for finer tuning. ' )
2017-09-29 11:57:34 +00:00
2017-06-23 15:20:46 +00:00
parser . add_argument ( ' --dsm ' ,
2017-04-06 13:06:09 +00:00
action = ' store_true ' ,
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 '
2019-04-20 14:56:42 +00:00
' morphological filter. Check the --dem* parameters for finer tuning. ' )
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> ' ,
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. '
2017-06-23 20:38:01 +00:00
' \n Default= %(default)s ' )
2017-04-06 19:37:13 +00:00
parser . add_argument ( ' --dem-resolution ' ,
metavar = ' <float> ' ,
type = float ,
2018-08-08 13:37:51 +00:00
default = 5 ,
help = ' DSM/DTM resolution in cm / pixel. '
2017-04-06 19:37:13 +00:00
' \n Default: %(default)s ' )
2017-06-23 15:20:46 +00:00
parser . add_argument ( ' --dem-decimation ' ,
metavar = ' <positive integer> ' ,
default = 1 ,
type = int ,
help = ' Decimate the points before generating the DEM. 1 is no decimation (full quality). '
2017-06-23 20:15:13 +00:00
' 100 decimates ~99 %% of the points. Useful for speeding up '
2017-06-23 15:20:46 +00:00
' generation. \n Default= %(default)s ' )
2019-04-29 21:35:12 +00:00
parser . add_argument ( ' --dem-euclidean-map ' ,
action = ' store_true ' ,
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> ' ,
2018-08-08 13:37:51 +00:00
default = 5 ,
2016-03-08 18:26:58 +00:00
type = float ,
2018-08-08 13:37:51 +00:00
help = ( ' Orthophoto resolution in cm / pixel. \n '
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 ' ,
action = ' store_true ' ,
default = False ,
help = ' Set this parameter if you want a stripped geoTIFF. \n '
' Default: %(default)s ' )
2019-10-24 15:48:21 +00:00
parser . add_argument ( ' --orthophoto-png ' ,
action = ' store_true ' ,
default = False ,
help = ' Set this parameter if you want to generate a PNG rendering of the orthophoto. \n '
' 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> ' ,
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 ' ,
help = ' Set the compression to use. Note that this could '
' break gdal_translate if you don \' t know what you '
' are doing. Options: %(choices)s . \n Default: %(default)s ' )
2019-04-29 21:35:12 +00:00
parser . add_argument ( ' --orthophoto-cutline ' ,
action = ' store_true ' ,
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
2017-03-31 18:53:47 +00:00
parser . add_argument ( ' --build-overviews ' ,
action = ' store_true ' ,
default = False ,
help = ' Build orthophoto overviews using gdaladdo. ' )
2016-12-20 19:34:51 +00:00
parser . add_argument ( ' --verbose ' , ' -v ' ,
2016-12-11 22:16:11 +00:00
action = ' store_true ' ,
2017-03-27 19:41:51 +00:00
default = False ,
2016-12-11 22:16:11 +00:00
help = ' Print additional messages to the console \n '
' Default: %(default)s ' )
2016-03-08 18:26:58 +00:00
parser . add_argument ( ' --time ' ,
action = ' store_true ' ,
2017-03-27 19:41:51 +00:00
default = False ,
2016-03-08 18:26:58 +00:00
help = ' Generates a benchmark file with runtime info \n '
' Default: %(default)s ' )
2019-06-28 15:10:08 +00:00
parser . add_argument ( ' --debug ' ,
action = ' store_true ' ,
default = False ,
help = ' Print debug messages \n '
' 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 ' ,
version = ' OpenDroneMap {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 ,
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 '
' each cluster should have on average. ' )
2019-04-23 17:59:54 +00:00
parser . add_argument ( ' --split-overlap ' ,
2019-04-23 01:42:32 +00:00
type = float ,
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 '
' that neighboring submodels overlap. ' )
2019-05-05 18:32:57 +00:00
parser . add_argument ( ' --sm-cluster ' ,
metavar = ' <string> ' ,
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> ' ,
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 ' ,
action = ' store_true ' ,
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 ' ) )
2019-08-13 17:04:38 +00:00
2017-03-27 19:41:51 +00:00
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 )
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
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 )
2017-03-27 19:41:51 +00:00
return args