149 lines
5.3 KiB
Markdown
149 lines
5.3 KiB
Markdown
# Kamera-Anzahl-Studie
|
|
|
|
Untersucht, wie sich die Pose-Schätzgenauigkeit verändert, wenn weniger Kameras
|
|
verwendet werden. Hauptergebnis ist eine Kurve **k Kameras → Positionsfehler in mm**
|
|
an zwei Punkten des Roboters (Handgelenk und Finger).
|
|
|
|
Hintergrundfrage und Entscheidungslogik: [`doc/camera_number_roadmap.md`](../../doc/camera_number_roadmap.md)
|
|
|
|
---
|
|
|
|
## Voraussetzungen
|
|
|
|
Pro Szene müssen vorhanden sein:
|
|
|
|
| Datei | Woher |
|
|
|---|---|
|
|
| `data/simulation/SceneX/render_*.png` | Blender-Renderer |
|
|
| `data/simulation/SceneX/render_*.npz` | Kamera-Intrinsik |
|
|
| `data/simulation/SceneX/pose.json` | Ground-Truth-Pose |
|
|
| `data/robot/robot.json` | Robotermodell |
|
|
|
|
Neue Szenen werden **automatisch erkannt** — kein Skript anpassen nötig.
|
|
Für die Plots zusätzlich `matplotlib` (`pip install matplotlib`); ohne läuft
|
|
alles, nur das PNG entfällt.
|
|
|
|
---
|
|
|
|
## Metriken
|
|
|
|
Pro Kamera-Subset werden zwei Positionsfehler per Vorwärtskinematik berechnet —
|
|
der euklidische Abstand zwischen geschätzter und wahrer Position eines Punktes:
|
|
|
|
| Metrik | Punkt | Hängt ab von | Bedeutung |
|
|
|---|---|---|---|
|
|
| `wrist_error_mm` | Hand-Ursprung | Armgelenke `x,y,z,a` | Wie genau ist der Arm bis zum Handgelenk? |
|
|
| `finger_error_mm` | FingerA-Skelettspitze | volle Kette `x..e` | Wie genau ist die ganze Pose inkl. Hand/Finger? |
|
|
|
|
**Unbeobachtbare Gelenke → leerer Wert (n/a).** Sieht ein Subset z. B. die Hand
|
|
nicht, ist `b/c/e` unbeobachtbar — dann ist die *wahre* Fingerposition schlicht
|
|
unbekannt und `finger_error_mm` bleibt **leer** (statt mit einer falschen 0
|
|
gefüllt zu werden). Das Handgelenk hängt nur von den Armgelenken ab und ist
|
|
deshalb meist auch mit wenigen Kameras bestimmbar.
|
|
|
|
Welche Gelenke einen Punkt bewegen, wird **numerisch** ermittelt (kleine
|
|
Auslenkung je Gelenk) — funktioniert daher auch, wenn sich das Robotermodell ändert.
|
|
|
|
Zusätzliche Spalten:
|
|
- `n_unobservable` — Anzahl der 7 Gelenke, die in diesem Subset unbeobachtbar waren.
|
|
- `mean_abs_deg` / `max_abs_deg` — Gelenkwinkelfehler (nur **beobachtbare** Gelenke).
|
|
- `mean_abs_mm` / `max_abs_mm` — Lineargelenkfehler (`x`, `e`).
|
|
|
|
---
|
|
|
|
## Schritt 1 — Studie laufen lassen
|
|
|
|
```bat
|
|
run\run_camera_study.bat
|
|
```
|
|
|
|
Das wertet alle verfügbaren Szenen aus, k = 3 bis (alle verfügbaren Kameras),
|
|
10 zufällige Subsets pro k.
|
|
|
|
**Optionen:**
|
|
|
|
```bat
|
|
REM Nur bestimmte Szenen
|
|
run\run_camera_study.bat --scenes Scene7 Scene9
|
|
|
|
REM Kamerabereich einschränken
|
|
run\run_camera_study.bat --k-min 3 --k-max 5
|
|
|
|
REM Weniger Samples — schneller, weniger repräsentativ
|
|
run\run_camera_study.bat --samples 3
|
|
|
|
REM Pipeline für vorhandene Subsets erneut laufen lassen
|
|
run\run_camera_study.bat --force
|
|
|
|
REM VOLLSTÄNDIGER Neustart: alles löschen und neu rechnen
|
|
run\run_camera_study.bat --clean
|
|
|
|
REM Nur eine re-gerenderte Szene komplett neu rechnen (Rest bleibt erhalten)
|
|
run\run_camera_study.bat --clean --scenes Scene10
|
|
```
|
|
|
|
**Drei Stufen der Wiederholung:**
|
|
|
|
| Flag | Wirkung |
|
|
|---|---|
|
|
| *(kein Flag)* | Vorhandene `robot_state.json` werden wiederverwendet, nur Auswertung neu. Schnell. |
|
|
| `--force` | Pipeline läuft erneut. Für geänderte Pipeline-Logik. |
|
|
| `--clean` | Löscht Zwischenergebnisse vorher. **Nötig nach Re-Rendering.** |
|
|
|
|
**Merge:** Ein Lauf über einzelne Szenen aktualisiert nur deren Zeilen in
|
|
`camera_study.json/.csv` — die übrigen Szenen bleiben erhalten.
|
|
|
|
---
|
|
|
|
## Schritt 2 — Auswertung
|
|
|
|
```bash
|
|
python benchmark/camera_count/analyze.py # finger_error_mm (Standard)
|
|
python benchmark/camera_count/analyze.py --metric wrist_error_mm
|
|
python benchmark/camera_count/analyze.py --metric mean_abs_deg
|
|
```
|
|
|
|
Beispielausgabe:
|
|
|
|
```
|
|
Kamera-Anzahl vs. finger_error_mm
|
|
k | n | n/a | Mittel | Median | Std | Min | Max
|
|
--------------------------------------------------------------------------
|
|
3 | 4 | 6 | 1.775 | 1.583 | 0.986 | 0.710 | 3.225
|
|
4 | 10 | 0 | 1.955 | 2.034 | 0.696 | 0.503 | 3.317
|
|
...
|
|
7 | 1 | 0 | 1.251 | 1.251 | 0.000 | 1.251 | 1.251
|
|
|
|
n/a = Subsets, bei denen dieser Punkt unbeobachtbar war (nicht eingerechnet).
|
|
```
|
|
|
|
Bei k=3: **6 von 10 Subsets sehen den Finger gar nicht** (n/a=6). Das ist die
|
|
eigentliche Aussage — nicht „der Fehler ist klein", sondern „die meisten
|
|
3-Kamera-Anordnungen verlieren die Hand komplett".
|
|
|
|
Verfügbare Metriken: `finger_error_mm` (Standard), `wrist_error_mm`,
|
|
`mean_abs_deg`, `max_abs_deg`, `mean_abs_mm`, `max_abs_mm`.
|
|
|
|
---
|
|
|
|
## Ausgabedateien
|
|
|
|
| Pfad | Inhalt |
|
|
|---|---|
|
|
| `benchmark/camera_count/results/camera_study.json` | Alle Einzelergebnisse |
|
|
| `benchmark/camera_count/results/camera_study.csv` | Dasselbe als CSV (inkl. `wrist_error_mm`, `finger_error_mm`, `n_unobservable`) |
|
|
| `benchmark/camera_count/results/camera_count_<metric>.png` | Boxplot je Metrik |
|
|
| `data/camera_study/SceneX/k3_abc/` | Pipeline-Zwischenergebnisse pro Subset |
|
|
|
|
Die Zwischenergebnisse in `data/camera_study/` sind groß — nicht committen.
|
|
|
|
---
|
|
|
|
## Ergebnis interpretieren
|
|
|
|
1. **Wird die Hand überhaupt gesehen?** → `n/a`-Spalte bei `finger_error_mm`.
|
|
2. **Ab welchem k wird der Fehler stabil?** → Knick in der Kurve.
|
|
3. **Welche Kombination ist bei kleinem k am besten?** → beste/schlechteste Subsets.
|
|
4. **Arm vs. Hand getrennt:** `wrist_error_mm` ist meist schon mit 3 Kameras gut;
|
|
der kritische Teil ist die Hand/Finger-Orientierung.
|