-
Notifications
You must be signed in to change notification settings - Fork 1.1k
/
odm_app.py
120 lines (102 loc) · 5.51 KB
/
odm_app.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
import os, traceback, sys
from opendm import context
from opendm import types
from opendm import io
from opendm import system
from opendm import log
from stages.dataset import ODMLoadDatasetStage
from stages.run_opensfm import ODMOpenSfMStage
from stages.openmvs import ODMOpenMVSStage
from stages.odm_meshing import ODMeshingStage
from stages.mvstex import ODMMvsTexStage
from stages.odm_georeferencing import ODMGeoreferencingStage
from stages.odm_orthophoto import ODMOrthoPhotoStage
from stages.odm_dem import ODMDEMStage
from stages.odm_filterpoints import ODMFilterPoints
from stages.splitmerge import ODMSplitStage, ODMMergeStage
from stages.odm_report import ODMReport
from stages.odm_postprocess import ODMPostProcess
class ODMApp:
def __init__(self, args):
"""
Initializes the application and defines the ODM application pipeline stages
"""
json_log_paths = [os.path.join(args.project_path, "log.json")]
if args.copy_to:
json_log_paths.append(args.copy_to)
log.logger.init_json_output(json_log_paths, args)
dataset = ODMLoadDatasetStage('dataset', args, progress=5.0)
split = ODMSplitStage('split', args, progress=75.0)
merge = ODMMergeStage('merge', args, progress=100.0)
opensfm = ODMOpenSfMStage('opensfm', args, progress=25.0)
openmvs = ODMOpenMVSStage('openmvs', args, progress=50.0)
filterpoints = ODMFilterPoints('odm_filterpoints', args, progress=52.0)
meshing = ODMeshingStage('odm_meshing', args, progress=60.0,
max_vertex=args.mesh_size,
oct_tree=max(1, min(14, args.mesh_octree_depth)),
samples=1.0,
point_weight=4.0,
max_concurrency=args.max_concurrency)
texturing = ODMMvsTexStage('mvs_texturing', args, progress=70.0)
georeferencing = ODMGeoreferencingStage('odm_georeferencing', args, progress=80.0,
gcp_file=args.gcp)
dem = ODMDEMStage('odm_dem', args, progress=90.0,
max_concurrency=args.max_concurrency)
orthophoto = ODMOrthoPhotoStage('odm_orthophoto', args, progress=98.0)
report = ODMReport('odm_report', args, progress=99.0)
postprocess = ODMPostProcess('odm_postprocess', args, progress=100.0)
# Normal pipeline
self.first_stage = dataset
dataset.connect(split) \
.connect(merge) \
.connect(opensfm)
if args.fast_orthophoto:
opensfm.connect(filterpoints)
else:
opensfm.connect(openmvs) \
.connect(filterpoints)
filterpoints \
.connect(meshing) \
.connect(texturing) \
.connect(georeferencing) \
.connect(dem) \
.connect(orthophoto) \
.connect(report) \
.connect(postprocess)
def execute(self):
try:
self.first_stage.run()
log.logger.log_json_success()
return 0
except system.SubprocessException as e:
print("")
print("===== Dumping Info for Geeks (developers need this to fix bugs) =====")
print(str(e))
stack_trace = traceback.format_exc()
print(stack_trace)
print("===== Done, human-readable information to follow... =====")
print("")
code = e.errorCode
log.logger.log_json_stage_error(str(e), code, stack_trace)
if code == 139 or code == 134 or code == 1 or code == 3221225477:
# Segfault
log.ODM_ERROR("Uh oh! Processing stopped because of strange values in the reconstruction. This is often a sign that the input data has some issues or the software cannot deal with it. Have you followed best practices for data acquisition? See https://docs.opendronemap.org/flying/")
elif code == 137 or code == 3221226505:
log.ODM_ERROR("Whoops! You ran out of memory! Add more RAM to your computer, if you're using docker configure it to use more memory, for WSL2 make use of .wslconfig (https://docs.microsoft.com/en-us/windows/wsl/wsl-config#configure-global-options-with-wslconfig), resize your images, lower the quality settings or process the images using a cloud provider (e.g. https://webodm.net).")
elif code == 132:
log.ODM_ERROR("Oh no! It looks like your CPU is not supported (is it fairly old?). You can still use ODM, but you will need to build your own docker image. See https://github.com/OpenDroneMap/ODM#build-from-source")
elif code == 3:
log.ODM_ERROR("ODM can't find a program that is required for processing to run! Did you do a custom build of ODM? (cool!) Make sure that all programs required by ODM are in the right place and are built correctly.")
else:
log.ODM_ERROR("The program exited with a strange error code. Please report it at https://community.opendronemap.org")
# TODO: more?
return code
except system.ExitException as e:
log.ODM_ERROR(str(e))
log.logger.log_json_stage_error(str(e), 1, traceback.format_exc())
sys.exit(1)
except Exception as e:
log.logger.log_json_stage_error(str(e), 1, traceback.format_exc())
raise e
finally:
log.logger.close()