Files
appRobotRender/benchmark/camera_count

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 14). 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:

  1. Wird die Hand überhaupt gesehen?n/a-Spalte bei finger_error_mm. Viele n/a bei k=3 heißt: zu wenige Kameras verlieren die Hand systematisch.

  2. Ab welchem k wird der Fehler stabil? → Knick in der Kurve zeigt den Sättigungspunkt.

  3. Welche Kamera-Kombination ist bei kleinem k am besten?analyze.py gibt beste und schlechteste Subsets aus.

  4. 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.)