stabilo-benchmark 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- stabilo_benchmark/__init__.py +8 -0
- stabilo_benchmark/__main__.py +15 -0
- stabilo_benchmark/annotation.py +72 -0
- stabilo_benchmark/cfg/pipelines.yaml +131 -0
- stabilo_benchmark/cli.py +715 -0
- stabilo_benchmark/config.py +391 -0
- stabilo_benchmark/datasets.py +322 -0
- stabilo_benchmark/environment.py +129 -0
- stabilo_benchmark/gcp.py +539 -0
- stabilo_benchmark/masking.py +458 -0
- stabilo_benchmark/metrics/__init__.py +59 -0
- stabilo_benchmark/metrics/diagnostics.py +222 -0
- stabilo_benchmark/metrics/geometric.py +321 -0
- stabilo_benchmark/metrics/photometric.py +196 -0
- stabilo_benchmark/oracle.py +188 -0
- stabilo_benchmark/perturbations.py +259 -0
- stabilo_benchmark/pipelines.py +333 -0
- stabilo_benchmark/regions.py +396 -0
- stabilo_benchmark/report/__init__.py +35 -0
- stabilo_benchmark/report/annotate_gcp.py +932 -0
- stabilo_benchmark/report/audit_figure.py +612 -0
- stabilo_benchmark/report/build.py +1859 -0
- stabilo_benchmark/report/capture.py +1082 -0
- stabilo_benchmark/report/case_figure.py +222 -0
- stabilo_benchmark/report/contrasts.py +696 -0
- stabilo_benchmark/report/figures.py +999 -0
- stabilo_benchmark/report/margin.py +253 -0
- stabilo_benchmark/report/names.py +61 -0
- stabilo_benchmark/report/repeats.py +105 -0
- stabilo_benchmark/report/scenes.py +94 -0
- stabilo_benchmark/report/survey_cases.py +155 -0
- stabilo_benchmark/report/tables.py +1824 -0
- stabilo_benchmark/report/trial_figure.py +399 -0
- stabilo_benchmark/resources.py +153 -0
- stabilo_benchmark/results.py +494 -0
- stabilo_benchmark/runners/__init__.py +5 -0
- stabilo_benchmark/runners/audit.py +461 -0
- stabilo_benchmark/runners/dynamic.py +957 -0
- stabilo_benchmark/runners/fetch.py +595 -0
- stabilo_benchmark/runners/prepare.py +430 -0
- stabilo_benchmark/runners/static.py +466 -0
- stabilo_benchmark/runners/survey.py +811 -0
- stabilo_benchmark/sampling.py +286 -0
- stabilo_benchmark/scene.py +393 -0
- stabilo_benchmark/seeding.py +47 -0
- stabilo_benchmark/stats.py +293 -0
- stabilo_benchmark/trial_cache.py +166 -0
- stabilo_benchmark-1.0.0.dist-info/METADATA +747 -0
- stabilo_benchmark-1.0.0.dist-info/RECORD +53 -0
- stabilo_benchmark-1.0.0.dist-info/WHEEL +5 -0
- stabilo_benchmark-1.0.0.dist-info/entry_points.txt +2 -0
- stabilo_benchmark-1.0.0.dist-info/licenses/LICENSE +21 -0
- stabilo_benchmark-1.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
# Author: Robert Fonod (robert.fonod@ieee.org)
|
|
4
|
+
|
|
5
|
+
"""Allow `python -m stabilo_benchmark <command>` to behave like the console script."""
|
|
6
|
+
|
|
7
|
+
import sys
|
|
8
|
+
|
|
9
|
+
from stabilo_benchmark.cli import main
|
|
10
|
+
|
|
11
|
+
if __name__ == '__main__':
|
|
12
|
+
# sys.exit, not a bare call: the console-script wrapper setuptools generates exits with
|
|
13
|
+
# main()'s return value, and `python -m` must agree with it. Discarding it made every
|
|
14
|
+
# invocation succeed, so a scripted campaign would run on past a failed stage.
|
|
15
|
+
sys.exit(main())
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
# Author: Robert Fonod (robert.fonod@ieee.org)
|
|
4
|
+
|
|
5
|
+
"""
|
|
6
|
+
annotation.py - The two hbb2obb commands that annotate an image directory.
|
|
7
|
+
|
|
8
|
+
<root>/
|
|
9
|
+
images/ the frames
|
|
10
|
+
labels_hbb/ hbb2obb-detect: horizontal boxes, absolute pixels
|
|
11
|
+
labels_obb/ hbb2obb: oriented boxes, one per horizontal box, same order
|
|
12
|
+
labels_confidence/ hbb2obb: per-box conversion score (0.0 marks an HBB fallback)
|
|
13
|
+
PROVENANCE_hbb.txt hbb2obb-detect: command, settings, checkpoint SHA-256
|
|
14
|
+
PROVENANCE_obb.txt hbb2obb: the same for the conversion
|
|
15
|
+
|
|
16
|
+
The detector is hbb2obb's registered `geotrax` model; the conversion settings are those selected
|
|
17
|
+
for Songdo Vision OBB. The README prints the same two commands, and `tests/test_samples.py`
|
|
18
|
+
checks that they match.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
from __future__ import annotations
|
|
22
|
+
|
|
23
|
+
import shutil
|
|
24
|
+
import subprocess
|
|
25
|
+
import sys
|
|
26
|
+
from pathlib import Path
|
|
27
|
+
from typing import List, Optional
|
|
28
|
+
|
|
29
|
+
DETECT_ARGS = ['--model', 'geotrax', '--no_confidence', '--save_provenance']
|
|
30
|
+
# fmt: off
|
|
31
|
+
CONVERT_ARGS = [
|
|
32
|
+
'--sam_models', 'sam_l',
|
|
33
|
+
'--imgsz', '1024',
|
|
34
|
+
'--scale_factors', '0.02',
|
|
35
|
+
'--opening_kernel_percentage', '-0.1',
|
|
36
|
+
'--fragment_ratio', '0.1',
|
|
37
|
+
'--confidence_dir',
|
|
38
|
+
'--save_provenance',
|
|
39
|
+
]
|
|
40
|
+
# fmt: on
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class AnnotationError(RuntimeError):
|
|
44
|
+
"""Raised when an hbb2obb command is missing or fails."""
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def commands(images_dir: Path, device: Optional[str] = None, overwrite: bool = False) -> List[List[str]]:
|
|
48
|
+
"""The hbb2obb-detect and hbb2obb command lines for an image directory."""
|
|
49
|
+
device_args = ['--device', str(device)] if device else []
|
|
50
|
+
detect = ['hbb2obb-detect', str(images_dir), *DETECT_ARGS, *device_args, *(['--overwrite'] if overwrite else [])]
|
|
51
|
+
convert = ['hbb2obb', str(images_dir), *CONVERT_ARGS, *device_args]
|
|
52
|
+
return [detect, convert]
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def annotate(images_dir: Path, device: Optional[str] = None, overwrite: bool = False) -> None:
|
|
56
|
+
"""Run both commands; labels land beside `images_dir`."""
|
|
57
|
+
for command in commands(Path(images_dir), device=device, overwrite=overwrite):
|
|
58
|
+
executable = _executable(command[0])
|
|
59
|
+
result = subprocess.run([executable, *command[1:]], check=False)
|
|
60
|
+
if result.returncode != 0:
|
|
61
|
+
raise AnnotationError(f"{' '.join(command)} exited with status {result.returncode}")
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def _executable(name: str) -> str:
|
|
65
|
+
"""The console script beside this interpreter first, so an unactivated venv still finds it."""
|
|
66
|
+
beside = Path(sys.executable).parent / name
|
|
67
|
+
if beside.is_file():
|
|
68
|
+
return str(beside)
|
|
69
|
+
found = shutil.which(name)
|
|
70
|
+
if found is None:
|
|
71
|
+
raise AnnotationError(f"'{name}' was not found. It is installed with hbb2obb: pip install hbb2obb")
|
|
72
|
+
return found
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
# =============================================================================
|
|
2
|
+
# stabilo-benchmark - named registration pipeline presets
|
|
3
|
+
# =============================================================================
|
|
4
|
+
# Each entry is a partial set of stabilo `Stabilizer` keyword arguments; keys absent from
|
|
5
|
+
# stabilo's cfg/default.yaml are rejected by `pipelines.validate_spec`.
|
|
6
|
+
#
|
|
7
|
+
# `masking` (none | hbb | obb) is an experiment-config axis, and `mask_use` is derived from it;
|
|
8
|
+
# neither is set here.
|
|
9
|
+
#
|
|
10
|
+
# `extends: <name>` inherits from another preset; keys given locally win.
|
|
11
|
+
#
|
|
12
|
+
# `filter_ratio` and `ransac_epipolar_threshold` of each benchmarked preset are its mAA-optimal point
|
|
13
|
+
# in configs/songdo/static/tuning.yaml, on the tuning scenes. LightGlue and LoFTR do not apply the ratio
|
|
14
|
+
# test, so only the threshold is set for them.
|
|
15
|
+
# =============================================================================
|
|
16
|
+
|
|
17
|
+
# -----------------------------------------------------------------------------
|
|
18
|
+
# Shared baseline; every preset inherits from it.
|
|
19
|
+
# -----------------------------------------------------------------------------
|
|
20
|
+
base:
|
|
21
|
+
matcher_name: bf
|
|
22
|
+
filter_type: ratio
|
|
23
|
+
filter_ratio: 0.9
|
|
24
|
+
transformation_type: projective
|
|
25
|
+
ransac_method: 38 # MAGSAC++
|
|
26
|
+
ransac_epipolar_threshold: 2.0
|
|
27
|
+
ransac_max_iter: 5000
|
|
28
|
+
ransac_confidence: 0.999999
|
|
29
|
+
clahe: false
|
|
30
|
+
downsample_ratio: 1.0 # matched operating point, from configs/songdo/static/budget.yaml
|
|
31
|
+
max_features: 8000
|
|
32
|
+
ref_multiplier: 2.0
|
|
33
|
+
mask_margin_ratio: 0.15
|
|
34
|
+
|
|
35
|
+
# -----------------------------------------------------------------------------
|
|
36
|
+
# Classical detectors (OpenCV).
|
|
37
|
+
# -----------------------------------------------------------------------------
|
|
38
|
+
orb:
|
|
39
|
+
extends: base
|
|
40
|
+
detector_name: orb
|
|
41
|
+
filter_ratio: 0.85
|
|
42
|
+
ransac_epipolar_threshold: 4.0
|
|
43
|
+
|
|
44
|
+
sift:
|
|
45
|
+
extends: base
|
|
46
|
+
detector_name: sift
|
|
47
|
+
filter_ratio: 0.7
|
|
48
|
+
ransac_epipolar_threshold: 0.5
|
|
49
|
+
|
|
50
|
+
rsift:
|
|
51
|
+
extends: base
|
|
52
|
+
detector_name: rsift
|
|
53
|
+
filter_ratio: 0.7
|
|
54
|
+
ransac_epipolar_threshold: 0.5
|
|
55
|
+
|
|
56
|
+
brisk:
|
|
57
|
+
extends: base
|
|
58
|
+
detector_name: brisk
|
|
59
|
+
filter_ratio: 0.7
|
|
60
|
+
ransac_epipolar_threshold: 1.5
|
|
61
|
+
|
|
62
|
+
kaze:
|
|
63
|
+
extends: base
|
|
64
|
+
detector_name: kaze
|
|
65
|
+
filter_ratio: 0.7
|
|
66
|
+
ransac_epipolar_threshold: 0.5
|
|
67
|
+
|
|
68
|
+
akaze:
|
|
69
|
+
extends: base
|
|
70
|
+
detector_name: akaze
|
|
71
|
+
filter_ratio: 0.7
|
|
72
|
+
ransac_epipolar_threshold: 4.0
|
|
73
|
+
|
|
74
|
+
# -----------------------------------------------------------------------------
|
|
75
|
+
# Learning-based detectors / matchers (kornia, via stabilo >= 1.4.0).
|
|
76
|
+
#
|
|
77
|
+
# `pipelines.check_resolution` warns when a preset exceeds Stabilizer.DL_PIXEL_BUDGETS; a
|
|
78
|
+
# configuration the machine cannot hold is recorded as infeasible and reported as N/A.
|
|
79
|
+
#
|
|
80
|
+
# xfeat / disk / dedode / loftr are upright models: matching degrades past roughly 30 degrees of
|
|
81
|
+
# in-plane rotation. keynet estimates keypoint orientation.
|
|
82
|
+
#
|
|
83
|
+
# lightglue accepts only the detectors in Stabilizer.LIGHTGLUE_FEATURE_NAMES (disk, dedode,
|
|
84
|
+
# keynet), not xfeat.
|
|
85
|
+
# -----------------------------------------------------------------------------
|
|
86
|
+
xfeat:
|
|
87
|
+
extends: base
|
|
88
|
+
detector_name: xfeat
|
|
89
|
+
matcher_name: bf
|
|
90
|
+
filter_ratio: 0.7
|
|
91
|
+
ransac_epipolar_threshold: 2.0
|
|
92
|
+
|
|
93
|
+
disk_lightglue:
|
|
94
|
+
extends: base
|
|
95
|
+
detector_name: disk
|
|
96
|
+
matcher_name: lightglue
|
|
97
|
+
ransac_epipolar_threshold: 2.0
|
|
98
|
+
|
|
99
|
+
dedode_lightglue:
|
|
100
|
+
extends: base
|
|
101
|
+
detector_name: dedode
|
|
102
|
+
matcher_name: lightglue
|
|
103
|
+
ransac_epipolar_threshold: 1.0
|
|
104
|
+
dedode_detector_weights: L-C4-v2
|
|
105
|
+
dedode_descriptor_weights: B-upright
|
|
106
|
+
|
|
107
|
+
keynet_lightglue:
|
|
108
|
+
extends: base
|
|
109
|
+
detector_name: keynet
|
|
110
|
+
matcher_name: lightglue
|
|
111
|
+
ransac_epipolar_threshold: 4.0
|
|
112
|
+
|
|
113
|
+
loftr:
|
|
114
|
+
extends: base
|
|
115
|
+
detector_name: loftr # detector-free: matcher_name / filter_type are ignored
|
|
116
|
+
loftr_weights: outdoor
|
|
117
|
+
loftr_confidence: 0.0
|
|
118
|
+
|
|
119
|
+
# -----------------------------------------------------------------------------
|
|
120
|
+
# Reference estimator (pseudo-ground truth) for the dynamic benchmark: the sift preset with its
|
|
121
|
+
# tuned ratio test and inlier threshold, at full resolution with a larger feature budget and a
|
|
122
|
+
# stricter estimator. Its error is bounded by `stabilo-benchmark audit`.
|
|
123
|
+
# -----------------------------------------------------------------------------
|
|
124
|
+
oracle:
|
|
125
|
+
extends: sift
|
|
126
|
+
downsample_ratio: 1.0
|
|
127
|
+
max_features: 20000
|
|
128
|
+
ref_multiplier: 2.0
|
|
129
|
+
ransac_max_iter: 20000
|
|
130
|
+
ransac_confidence: 0.9999999
|
|
131
|
+
mask_margin_ratio: 0.20
|