Files
appRobotRender/benchmark/camera_count/README.md
2026-06-03 07:30:28 +02:00

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.