kopia lustrzana https://github.com/OpenDroneMap/ODM
Simplified DTM options, fixed SMRF param ranges
rodzic
5ad5e226d7
commit
cbe3b1544b
|
@ -297,13 +297,10 @@ def config():
|
|||
'Default: %(default)s'))
|
||||
|
||||
parser.add_argument('--pc-classify',
|
||||
metavar='<string>',
|
||||
default='none',
|
||||
choices=['none', 'smrf', 'pmf'],
|
||||
help='Classify the point cloud outputs using either '
|
||||
'a Simple Morphological Filter or a Progressive Morphological Filter. '
|
||||
'If --dtm is set this parameter defaults to smrf. '
|
||||
'You can control the behavior of both smrf and pmf by tweaking the --dem-* parameters. '
|
||||
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. '
|
||||
'Default: '
|
||||
'%(default)s')
|
||||
|
||||
|
@ -431,23 +428,6 @@ def config():
|
|||
'are discarded. \nDefault: '
|
||||
'%(default)s')
|
||||
|
||||
parser.add_argument('--dem-initial-distance',
|
||||
metavar='<positive float>',
|
||||
type=float,
|
||||
default=0.15,
|
||||
help='Used to classify ground vs non-ground points. Set this value to account for Z noise in meters. '
|
||||
'If you have an uncertainty of around 15 cm, set this value large enough to not exclude these points. '
|
||||
'Too small of a value will exclude valid ground points, while too large of a value will misclassify non-ground points for ground ones. '
|
||||
'\nDefault: '
|
||||
'%(default)s')
|
||||
|
||||
parser.add_argument('--dem-approximate',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help='Use this tag use the approximate progressive '
|
||||
'morphological filter, which computes DEMs faster '
|
||||
'but is not as accurate.')
|
||||
|
||||
parser.add_argument('--dem-decimation',
|
||||
metavar='<positive integer>',
|
||||
default=1,
|
||||
|
@ -456,17 +436,6 @@ def config():
|
|||
'100 decimates ~99%% of the points. Useful for speeding up '
|
||||
'generation.\nDefault=%(default)s')
|
||||
|
||||
parser.add_argument('--dem-terrain-type',
|
||||
metavar='<string>',
|
||||
choices=['FlatNonForest', 'FlatForest', 'ComplexNonForest', 'ComplexForest'],
|
||||
default='ComplexForest',
|
||||
help='One of: %(choices)s. Specifies the type of terrain. This mainly helps reduce processing time. '
|
||||
'\nFlatNonForest: Relatively flat region with little to no vegetation'
|
||||
'\nFlatForest: Relatively flat region that is forested'
|
||||
'\nComplexNonForest: Varied terrain with little to no vegetation'
|
||||
'\nComplexForest: Varied terrain that is forested'
|
||||
'\nDefault=%(default)s')
|
||||
|
||||
parser.add_argument('--orthophoto-resolution',
|
||||
metavar='<float > 0.0>',
|
||||
default=5,
|
||||
|
@ -548,9 +517,9 @@ def config():
|
|||
log.ODM_INFO('Fast orthophoto is turned on, automatically setting --skip-3dmodel')
|
||||
args.skip_3dmodel = True
|
||||
|
||||
if args.dtm and args.pc_classify == 'none':
|
||||
if args.dtm and not args.pc_classify:
|
||||
log.ODM_INFO("DTM is turned on, automatically turning on point cloud classification")
|
||||
args.pc_classify = "smrf"
|
||||
args.pc_classify = True
|
||||
|
||||
if args.skip_3dmodel and args.use_3dmesh:
|
||||
log.ODM_WARNING('--skip-3dmodel is set, but so is --use-3dmesh. --use_3dmesh will be ignored.')
|
||||
|
|
|
@ -9,15 +9,11 @@ from functools import partial
|
|||
|
||||
from . import pdal
|
||||
|
||||
def classify(lasFile, smrf=False, slope=1, cellsize=3, maxWindowSize=10, maxDistance=1,
|
||||
approximate=False, initialDistance=0.7, verbose=False):
|
||||
def classify(lasFile, slope=0.15, cellsize=1, maxWindowSize=18, verbose=False):
|
||||
start = datetime.now()
|
||||
|
||||
try:
|
||||
if smrf:
|
||||
pdal.run_pdaltranslate_smrf(lasFile, lasFile, slope, cellsize, maxWindowSize, verbose)
|
||||
else:
|
||||
pdal.run_pdalground(lasFile, lasFile, slope, cellsize, maxWindowSize, maxDistance, approximate=approximate, initialDistance=initialDistance, verbose=verbose)
|
||||
except:
|
||||
raise Exception("Error creating classified file %s" % fout)
|
||||
|
||||
|
|
|
@ -233,33 +233,6 @@ def run_pipeline(json, verbose=False):
|
|||
os.remove(jsonfile)
|
||||
|
||||
|
||||
def run_pdalground(fin, fout, slope, cellsize, maxWindowSize, maxDistance, approximate=False, initialDistance=0.7, verbose=False):
|
||||
""" Run PDAL ground """
|
||||
cmd = [
|
||||
'pdal',
|
||||
'ground',
|
||||
'-i %s' % fin,
|
||||
'-o %s' % fout,
|
||||
'--slope %s' % slope,
|
||||
'--cell_size %s' % cellsize,
|
||||
'--initial_distance %s' % initialDistance
|
||||
]
|
||||
if maxWindowSize is not None:
|
||||
cmd.append('--max_window_size %s' %maxWindowSize)
|
||||
if maxDistance is not None:
|
||||
cmd.append('--max_distance %s' %maxDistance)
|
||||
|
||||
if approximate:
|
||||
cmd.append('--approximate')
|
||||
|
||||
if verbose:
|
||||
cmd.append('--developer-debug')
|
||||
print ' '.join(cmd)
|
||||
print ' '.join(cmd)
|
||||
out = system.run(' '.join(cmd))
|
||||
if verbose:
|
||||
print out
|
||||
|
||||
def run_pdaltranslate_smrf(fin, fout, slope, cellsize, maxWindowSize, verbose=False):
|
||||
""" Run PDAL translate """
|
||||
cmd = [
|
||||
|
|
|
@ -39,45 +39,33 @@ class ODMDEMCell(ecto.Cell):
|
|||
(args.rerun_from is not None and
|
||||
'odm_dem' in args.rerun_from)
|
||||
|
||||
log.ODM_INFO('Classify: ' + str(args.pc_classify != "none"))
|
||||
log.ODM_INFO('Classify: ' + str(args.pc_classify))
|
||||
log.ODM_INFO('Create DSM: ' + str(args.dsm))
|
||||
log.ODM_INFO('Create DTM: ' + str(args.dtm))
|
||||
log.ODM_INFO('DEM input file {0} found: {1}'.format(tree.odm_georeferencing_model_laz, str(las_model_found)))
|
||||
|
||||
# Setup terrain parameters
|
||||
terrain_params_map = {
|
||||
'flatnonforest': (1, 3),
|
||||
'flatforest': (1, 2),
|
||||
'complexnonforest': (5, 2),
|
||||
'complexforest': (10, 2)
|
||||
}
|
||||
terrain_params = terrain_params_map[args.dem_terrain_type.lower()]
|
||||
slope, cellsize = terrain_params
|
||||
slope, cellsize = (0.15, 1)
|
||||
|
||||
# define paths and create working directories
|
||||
odm_dem_root = tree.path('odm_dem')
|
||||
if not io.dir_exists(odm_dem_root):
|
||||
system.mkdir_p(odm_dem_root)
|
||||
|
||||
if args.pc_classify != "none" and las_model_found:
|
||||
if args.pc_classify and las_model_found:
|
||||
pc_classify_marker = os.path.join(odm_dem_root, 'pc_classify_done.txt')
|
||||
|
||||
if not io.file_exists(pc_classify_marker) or rerun_cell:
|
||||
log.ODM_INFO("Classifying {} using {}".format(tree.odm_georeferencing_model_laz, args.pc_classify))
|
||||
log.ODM_INFO("Classifying {} using Simple Morphological Filter".format(tree.odm_georeferencing_model_laz))
|
||||
commands.classify(tree.odm_georeferencing_model_laz,
|
||||
args.pc_classify == "smrf",
|
||||
slope,
|
||||
cellsize,
|
||||
approximate=args.dem_approximate,
|
||||
initialDistance=args.dem_initial_distance,
|
||||
verbose=args.verbose
|
||||
)
|
||||
|
||||
with open(pc_classify_marker, 'w') as f:
|
||||
f.write('Classify: {}\n'.format(args.pc_classify))
|
||||
f.write('Classify: smrf\n')
|
||||
f.write('Slope: {}\n'.format(slope))
|
||||
f.write('Cellsize: {}\n'.format(cellsize))
|
||||
f.write('Approximate: {}\n'.format(args.dem_approximate))
|
||||
f.write('InitialDistance: {}\n'.format(args.dem_initial_distance))
|
||||
|
||||
# Do we need to process anything here?
|
||||
if (args.dsm or args.dtm) and las_model_found:
|
||||
|
|
Ładowanie…
Reference in New Issue