104 lines
5.3 KiB
Markdown
104 lines
5.3 KiB
Markdown
# Roadmap: Kamera-/Linsenfehler simulieren (billige WebCams)
|
||
|
||
**Status:** ✅ umgesetzt (A–D) in `setup/generateSets/render_robot.py`, Parameter in
|
||
`robot.json → renderingInfo`. **A ist isoliert getestet** (deterministisches npz-Rauschen).
|
||
**B–D 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. B–D ä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 460–510, 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);
|
||
B–D dürfen pro Aufnahme zufällig sein.
|