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
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-Spitze | 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).
Hinweis: Winkelfehler zählen unbeobachtbare Gelenke nicht mit, die mm-Positionsfehler lassen sie als n/a aus. Beide blenden also dieselben Fälle aus — die
n/a-Spalte zeigt, wie oft das passiert.
Schritt 1 — Studie laufen lassen
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:
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
Oder direkt über Python (z. B. in einer Linux-Umgebung / Docker):
python benchmark/camera_count/run_camera_study.py --samples 10
Laufzeit & Wiederholläufe: Pro Kamera-Subset läuft die volle Pipeline
(Schritt 1–4). Bereits gerechnete Subsets werden übersprungen (kein --force
nötig für Fortsetzung) — die mm-Auswertung wird dabei trotzdem frisch berechnet,
ein erneuter Lauf ohne --force ist also schnell.
Drei Stufen der Wiederholung:
| Flag | Wirkung |
|---|---|
| (kein Flag) | Vorhandene robot_state.json werden wiederverwendet, nur die Auswertung neu gerechnet. Schnell. |
--force |
Pipeline läuft erneut, überschreibt robot_state.json. Für geänderte Pipeline-Logik. |
--clean |
Löscht Zwischenergebnisse vorher komplett. Nötig nach Re-Rendering. Ohne --scenes wird alles inkl. Ergebnisdateien zurückgesetzt; mit --scenes nur die genannten Szenen. |
Merge: Ein Lauf über einzelne Szenen (--scenes) aktualisiert nur deren
Zeilen in camera_study.json/.csv — die übrigen Szenen bleiben erhalten. Du
kannst also eine re-gerenderte Szene neu rechnen, ohne die Gesamtauswertung zu verlieren.
Schritt 2 — Auswertung
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 (nur Scene10):
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
5 | 10 | 0 | 1.391 | 1.322 | 0.646 | 0.614 | 2.468
6 | 7 | 0 | 1.306 | 1.288 | 0.389 | 0.697 | 1.992
7 | 1 | 0 | 1.251 | 1.251 | 0.000 | 1.251 | 1.251
n/a = Subsets, bei denen dieser Punkt unbeobachtbar war (nicht eingerechnet).
Beste / schlechteste Subsets je k (finger_error_mm):
k=3: best [Scene10] bcd (0.710) worst [Scene10] acf (3.225)
...
Hier sieht man sofort: bei k=3 konnten 6 von 10 Subsets den Finger gar nicht sehen (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 (Spalten 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
Die Studie beantwortet vier Fragen:
-
Wird die Hand überhaupt gesehen? →
n/a-Spalte beifinger_error_mm. Viele n/a bei k=3 heißt: zu wenige Kameras verlieren die Hand systematisch. -
Ab welchem k wird der Fehler stabil? → Knick in der Kurve zeigt den Sättigungspunkt.
-
Welche Kamera-Kombination ist bei kleinem k am besten? →
analyze.pygibt beste und schlechteste Subsets aus. -
Arm vs. Hand getrennt: Das Handgelenk (
wrist_error_mm) ist meist schon mit 3 Kameras gut bestimmt — der kritische Teil ist die Hand/Finger-Orientierung.
Eine praktische Entscheidungsregel: 3 Kameras gelten als ausreichend, wenn
(a) der Finger in fast allen Subsets beobachtbar ist (wenig n/a) und
(b) finger_error_mm bei k=3 nicht wesentlich schlechter ist als beim Maximum.
(Schwellwert je nach Anwendung anpassen.)