Skip to content

Commit 44a3d43

Browse files
committed
Refactor process.py: configuration parsing in its own method that can be used in other scripts
1 parent 64ff000 commit 44a3d43

File tree

1 file changed

+104
-86
lines changed

1 file changed

+104
-86
lines changed

python/cli/process/process.py

Lines changed: 104 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,92 @@ def define_subparser(subparsers):
3535
sub.set_defaults(func=process)
3636
return define_args(sub)
3737

38+
def parse_input_dir(input_dir):
39+
cameras = None
40+
calibrationJson = f"{input_dir}/calibration.json"
41+
if os.path.exists(calibrationJson):
42+
with open(calibrationJson) as f:
43+
calibration = json.load(f)
44+
if "cameras" in calibration:
45+
cameras = calibration["cameras"]
46+
device = None
47+
metadataJson = f"{input_dir}/metadata.json"
48+
if os.path.exists(metadataJson):
49+
with open(metadataJson) as f:
50+
metadata = json.load(f)
51+
if metadata.get("platform") == "ios":
52+
device = "ios-tof"
53+
if device == None:
54+
vioConfigYaml = f"{input_dir}/vio_config.yaml"
55+
if os.path.exists(vioConfigYaml):
56+
with open(vioConfigYaml) as file:
57+
supported = ['oak-d', 'k4a', 'realsense', 'orbbec-astra2', 'orbbec-femto', 'android', 'android-tof']
58+
for line in file:
59+
if "parameterSets" in line:
60+
for d in supported:
61+
if d in line:
62+
device = d
63+
break
64+
if device: break
65+
return (device, cameras)
66+
67+
def auto_config(device_preset,
68+
key_frame_distance=0.1,
69+
mono=False,
70+
icp=True,
71+
fast=False,
72+
already_rectified=False,
73+
internal=[]):
74+
75+
config = {
76+
"maxMapSize": 0,
77+
"useSlam": True,
78+
"passthroughColorImages": True,
79+
"keyframeDecisionDistanceThreshold": key_frame_distance,
80+
"icpVoxelSize": min(key_frame_distance, 0.1)
81+
}
82+
parameter_sets = ['wrapper-base']
83+
84+
if mono: config['useStereo'] = False
85+
86+
prefer_icp = icp and not mono
87+
88+
if not fast:
89+
parameter_sets.append('offline-base')
90+
# remove these to further trade off speed for quality
91+
mid_q = {
92+
'maxKeypoints': 1000,
93+
'optimizerMaxIterations': 30
94+
}
95+
for k, v in mid_q.items(): config[k] = v
96+
97+
if internal is not None:
98+
for param in internal:
99+
k, _, v = param.partition(':')
100+
config[k] = v
101+
102+
if device_preset:
103+
parameter_sets.append(device_preset)
104+
105+
if device_preset == 'k4a':
106+
if prefer_icp:
107+
parameter_sets.extend(['icp'])
108+
if not fast: parameter_sets.append('offline-icp')
109+
elif device_preset == 'realsense':
110+
if prefer_icp:
111+
parameter_sets.extend(['icp', 'realsense-icp'])
112+
if not fast: parameter_sets.append('offline-icp')
113+
elif device_preset == 'oak-d':
114+
config['stereoPointCloudMinDepth'] = 0.5
115+
config['alreadyRectified'] = already_rectified
116+
elif device_preset is not None and "orbbec" in device_preset:
117+
if prefer_icp:
118+
parameter_sets.extend(['icp'])
119+
if not fast: parameter_sets.append('offline-icp')
120+
121+
config['parameterSets'] = parameter_sets
122+
return config
123+
38124
def interpolate_missing_properties(df_source, df_query, k_nearest=3):
39125
import pandas as pd
40126
from scipy.spatial import KDTree
@@ -621,6 +707,7 @@ def on_mapping_output(output):
621707
raise
622708

623709
def is_already_rectified(input_dir):
710+
# hack for OAK-D
624711
vioConfigYaml = f"{input_dir}/vio_config.yaml"
625712
if os.path.exists(vioConfigYaml):
626713
with open(vioConfigYaml) as file:
@@ -630,122 +717,53 @@ def is_already_rectified(input_dir):
630717
return value.lower().strip() == "true"
631718
return False
632719

633-
def parse_input_dir(input_dir):
634-
cameras = None
635-
calibrationJson = f"{input_dir}/calibration.json"
636-
if os.path.exists(calibrationJson):
637-
with open(calibrationJson) as f:
638-
calibration = json.load(f)
639-
if "cameras" in calibration:
640-
cameras = calibration["cameras"]
641-
device = None
642-
metadataJson = f"{input_dir}/metadata.json"
643-
if os.path.exists(metadataJson):
644-
with open(metadataJson) as f:
645-
metadata = json.load(f)
646-
if metadata.get("platform") == "ios":
647-
device = "ios-tof"
648-
if device == None:
649-
vioConfigYaml = f"{input_dir}/vio_config.yaml"
650-
if os.path.exists(vioConfigYaml):
651-
with open(vioConfigYaml) as file:
652-
supported = ['oak-d', 'k4a', 'realsense', 'orbbec-astra2', 'orbbec-femto', 'android', 'android-tof']
653-
for line in file:
654-
if "parameterSets" in line:
655-
for d in supported:
656-
if d in line:
657-
device = d
658-
break
659-
if device: break
660-
return (device, cameras)
720+
device_preset, cameras = parse_input_dir(args.input)
661721

662-
config = {
663-
"maxMapSize": 0,
664-
"useSlam": True,
665-
"passthroughColorImages": True,
666-
"keyframeDecisionDistanceThreshold": args.key_frame_distance,
667-
"icpVoxelSize": min(args.key_frame_distance, 0.1)
668-
}
722+
if args.device_preset:
723+
device_preset = args.device_preset
669724

670-
parameter_sets = ['wrapper-base']
725+
if device_preset: print(f"Selected device type: {device_preset}", flush=True)
726+
else: print("Warning! Couldn't automatically detect device preset, to ensure best results suply one via --device_preset argument", flush=True)
727+
728+
useMono = args.mono or (cameras != None and len(cameras) == 1)
729+
730+
config = auto_config(device_preset,
731+
key_frame_distance=args.key_frame_distance,
732+
mono=useMono,
733+
icp=not args.no_icp,
734+
fast=args.fast,
735+
internal=args.internal,
736+
already_rectified=is_already_rectified(args.input)) # rectification required for stereo point cloud
671737

672738
tmp_dir = None
673739
if args.format in ['ply', 'pcd']:
674740
config["mapSavePath"] = args.output
675-
parameter_sets.append('point-cloud')
741+
config['parameterSets'].append('point-cloud')
676742
elif args.format == 'obj':
677743
assert not args.mono
678744
config['recMeshSavePath'] = args.output
679745
config['recTexturize'] = args.texturize
680-
parameter_sets.append('meshing')
746+
config['parameterSets'].append('meshing')
681747
else:
682748
# Clear output dir
683749
shutil.rmtree(f"{args.output}/images", ignore_errors=True)
684750
os.makedirs(f"{args.output}/images", exist_ok=True)
685751
tmp_dir = tempfile.mkdtemp()
686752

687-
device_preset, cameras = parse_input_dir(args.input)
688-
689753
if cameras is not None:
690754
cam = cameras[0]
691755
exposureTime = cam.get('exposureTimeSeconds', 0)
692756
rollingShutterTime = cam.get('shutterRollTimeSeconds', 0)
693757
if args.no_undistort:
694758
cameraDistortion = convert_distortion(cam)
695759

696-
useMono = args.mono or (cameras != None and len(cameras) == 1)
697-
698-
if useMono: config['useStereo'] = False
699-
700-
prefer_icp = not args.no_icp and not useMono
701-
702-
if not args.fast:
703-
parameter_sets.append('offline-base')
704-
# remove these to further trade off speed for quality
705-
mid_q = {
706-
'maxKeypoints': 1000,
707-
'optimizerMaxIterations': 30
708-
}
709-
for k, v in mid_q.items(): config[k] = v
710-
711-
if args.device_preset:
712-
device_preset = args.device_preset
713-
714-
if args.internal is not None:
715-
for param in args.internal:
716-
k, _, v = param.partition(':')
717-
config[k] = v
718-
719-
if device_preset: print(f"Selected device type: {device_preset}", flush=True)
720-
else: print("Warning! Couldn't automatically detect device preset, to ensure best results suply one via --device_preset argument", flush=True)
721-
722-
if device_preset:
723-
parameter_sets.append(device_preset)
724-
725-
if device_preset == 'k4a':
726-
if prefer_icp:
727-
parameter_sets.extend(['icp'])
728-
if not args.fast: parameter_sets.append('offline-icp')
729-
elif device_preset == 'realsense':
730-
if prefer_icp:
731-
parameter_sets.extend(['icp', 'realsense-icp'])
732-
if not args.fast: parameter_sets.append('offline-icp')
733-
elif device_preset == 'oak-d':
734-
config['stereoPointCloudMinDepth'] = 0.5
735-
config['alreadyRectified'] = is_already_rectified(args.input) # rectification required for stereo point cloud
736-
elif device_preset is not None and "orbbec" in device_preset:
737-
if prefer_icp:
738-
parameter_sets.extend(['icp'])
739-
if not args.fast: parameter_sets.append('offline-icp')
740-
741760
if args.preview3d:
742761
from spectacularAI.cli.visualization.visualizer import Visualizer, VisualizerArgs
743762
visArgs = VisualizerArgs()
744763
visArgs.targetFps = 30
745764
visArgs.showCameraModel = False
746765
visualizer = Visualizer(visArgs)
747766

748-
config['parameterSets'] = parameter_sets
749767
print(config)
750768

751769
replay = spectacularAI.Replay(args.input, mapperCallback = on_mapping_output, configuration = config, ignoreFolderConfiguration = True)

0 commit comments

Comments
 (0)