Files
appRobotRender/doc/lens_errors_roadmap.md
2026-06-02 11:37:29 +02:00

104 lines
5.3 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Roadmap: Kamera-/Linsenfehler simulieren (billige WebCams)
**Status:** ✅ umgesetzt (AD) in `setup/generateSets/render_robot.py`, Parameter in
`robot.json → renderingInfo`. **A ist isoliert getestet** (deterministisches npz-Rauschen).
**BD sind Compositor-Effekte und müssen einmal in Blender 4.5 visuell geprüft werden**
jeder Effekt ist in `try/except` gekapselt: ein API-Problem überspringt nur den betroffenen
Effekt mit Log-Warnung `[render][WARN] <effekt> skipped: ...`, der Render läuft weiter.
### Parameter (robot.json → renderingInfo)
| Effekt | Parameter | Beispiel |
|---|---|---|
| A Brennweiten-Restfehler | `focalErrorPct` | 0.5 (±%) |
| A Hauptpunkt-Versatz | `principalErrorPx` | 3.0 (±px) |
| A Rest-Verzeichnung | `residualDistortion` | [0.02, -0.01] (k1,k2) |
| B Linsenstaub | `lensDirt` / `lensDirtStrength` | true / 0.08 |
| C Vignette | `vignette` / `vignetteStrength` | true / 0.08 |
| C Rand-Unschärfe | `localizedBlur` / `localizedBlurStrength` | false / 0.15 |
| D Sensor-Rauschen | `sensorNoise` / `sensorNoiseStrength` | true / 0.01 |
| D chromat. Aberration | `lensDistortion` / `lensDistortionStrength` | true / 0.002 |
**Wichtig:** A verfälscht nur die **npz-Kalibrierung** (Bild bleibt ideal) → echter
geometrischer Härtetest gegen unvollständige Kalibrierung; deterministisch pro Kamera
(Seed aus `cameraPosition`), damit über alle Posen konsistent. BD ändern nur das **Bild**
(Detektion erschwert), nicht die Ground-Truth.
---
(Ursprüngliche Detailplanung als Referenz:)
**Ziel:** Realistische WebCam-Fehler in den Blender-Renderer (`setup/generateSets/render_robot.py`)
einbauen, um die Pose-Pipeline gegen reale Kamera-Imperfektionen zu härten — analog
zu den bereits umgesetzten Marker-Störungen (`markerOffsetMaxMm`, `motionBlur`, `arucoDust`).
## Kernkonzept (wichtig!)
Es gibt zwei Fehlerklassen:
1. **Geometrische Fehler** (Brennweite, Hauptpunkt, Verzeichnung): verschieben die
Marker-Pixel. **Entscheidend:** Kennt die Kalibrierung (`render_*.npz`) den Fehler
exakt, korrigiert die `undistort`-Kette ihn vollständig → *kein* Pose-Fehler. Den
Fehler erzeugt nur die **unvollständige Kalibrierung**. Daher: nicht „Bild verzeichnen",
sondern die **npz-Intrinsik leicht von der Wahrheit abweichen lassen** (Kalibrier-Restfehler).
2. **Photometrische Fehler** (Staub, Vignette, Rand-Unschärfe, Rauschen): ändern die npz
nicht, erschweren nur die Detektion (verrauschte Ecken, fehlende Marker).
## Hinweis: tote Parameter
In `robot.json → renderingInfo` existieren bereits, werden aber von `render_robot.py`
**nicht angewandt**: `lensDirt`, `lensDirtStrength`, `vignette`, `vignetteStrength`,
`sensorNoise`, `sensorNoiseStrength`, `lensDistortion`, `lensDistortionStrength`,
`localizedBlur`, `localizedBlurStrength`. Diese zum Leben erwecken.
## A — Kalibrier-Restfehler (geometrisch) ⭐ zuerst
Höchster Testwert, deckt eine Lücke der bisherigen Störungen ab. Modell-konsistent
(kein Blender↔OpenCV-Mismatch), weil das Bild ideal bleibt und nur die *angenommene*
Kalibrierung in der npz falsch ist.
**Implementierung:** im npz-Schreibblock von `render_robot.py` (~Zeile 460510, wo
`camera_matrix`/`dist_coeffs` gebaut werden) die Werte gezielt verrauschen —
**deterministisch pro Kamera** (Seed aus Kameraposition/-id), damit über alle Posen konsistent.
Neue robot.json-Parameter (Vorschlag):
- `focalErrorPct` (z. B. 0.5) → `fx,fy *= 1 ± rnd·focalErrorPct/100`
- `principalErrorPx` (z. B. 3) → `cx,cy += rnd·principalErrorPx`
- `residualDistortion` (z. B. [0.02, -0.01]) → kleine `k1,k2` in `dist_coeffs`,
die die Pipeline „korrigiert", obwohl das Bild ideal ist (Rest-Verzeichnung)
## B — Staub auf der Linse (photometrisch)
Halbtransparentes Schmutz-Overlay über dem *ganzen* Bild (Compositor), verdeckt zufällig
Marker teilweise. Parameter: `lensDirt`, `lensDirtStrength`.
**Implementierung:** Compositor — RenderLayers → Mix (über eine prozedurale Fleckentextur,
Voronoi/Noise mit hoher Schwelle) → Composite. Wenige, weiche, leicht abdunkelnde Flecken.
## C — Vignette + Rand-Unschärfe (Feldkrümmung)
Randabdunklung und radial nach außen zunehmende Unschärfe (billige Linsen sind am Rand
schlechter). Parameter: `vignette`/`vignetteStrength`, `localizedBlur`/`localizedBlurStrength`.
**Implementierung:** Compositor — Vignette via Ellipse-Maske × Bild; Rand-Unschärfe via
`CompositorNodeBlur` gemischt über eine radiale Maske (Lens Distortion „Distort" auf einer
Maske oder Ellipse-Maske als Mix-Faktor zwischen scharf und Blur).
## D — Sensor-Rauschen + chromatische Aberration
Leichtes Pixelrauschen und Farbsäume an Kanten. Parameter: `sensorNoise`/`sensorNoiseStrength`,
`lensDistortion`/`lensDistortionStrength` (Dispersion).
**Implementierung:** Compositor — additives Noise (klein) auf das Bild; chromatische
Aberration via `CompositorNodeLensdist` mit kleinem `dispersion`-Wert.
## Reihenfolge & Test
1. **A** (geometrisch, einfach, konsistent) — danach Benchmark *mit* vs. *ohne* laufen lassen.
2. **B + C** (Detektions-Robustheit).
3. **D** (Feinschliff).
Wichtig: Compositor-Node-API variiert leicht je Blender-Version — Code im echten Blender
(4.5) gegenchecken. Determinismus pro Kamera nur bei A nötig (geometrische Konsistenz);
BD dürfen pro Aufnahme zufällig sein.