image of commercial construction project

Einblicke in die Industrie

Aktuelle Entwicklungen, Trends und Fachanalysen aus Bau, Technik und digitaler Medienwelt – inklusive Updates zu Drohneneinsätzen, Solarwartung und Weblösungen.

Aktuelle Einblicke

Branchennews. Innovation. Fortschritt.

Neueste Entwicklungen und Fachbeiträge für Bauunternehmen, Ingenieurbüros und Dienstleister im Medienbereich.

Veröffentlicht am

30 November 2025

Autor

Maurice Lübeck

Überblick: Pipeline vom Bild zur sparse Pointcloud

Sehr grob besteht eine typische Pipeline aus:

  1. Bilder einlesen (RAW/JPG/PNG)
  2. Kameramodelle & Intrinsics bestimmen oder laden
  3. Undistortion: verzerrte Bilder → „Pinhole“-Ansicht
  4. Feature-Extraktion (z. B. SIFT) pro Bild
  5. Feature-Matching zwischen Bildpaaren
  6. Geometrische Verifikation: Fundamentalmatrix/Essentialmatrix, RANSAC
  7. Relative Kameraposen schätzen (Rotation $R_i$, Translation $t_i$)
  8. Triangulation von 3D-Punkten aus 2D-Korrespondenzen
  9. Bundle Adjustment: globales Optimieren von Kameras und 3D-Punkten
  10. Ergebnis: sparse Point Cloud + Kamera-Posen

Im Folgenden bauen wir das Schritt für Schritt mathematisch auf.


1. Pinhole-Kamera: von der 3D-Welt zum 2D-Sensor

1.1 Koordinatensysteme

Weltkoordinaten (globales Bezugssystem):

$$ X_w = \begin{pmatrix} X_w \\ Y_w \\ Z_w \end{pmatrix} $$

Kamerakoordinaten (Ursprung im Kamerazentrum):

$$ X_c = \begin{pmatrix} X_c \\ Y_c \\ Z_c \end{pmatrix} $$

Konvention (OpenCV-typisch):

  • $X$: nach rechts
  • $Y$: nach unten
  • $Z$: nach vorne aus der Kamera heraus

Extrinsics transformieren Welt → Kamera:

$$ X_c = R X_w + t $$

mit

  • $R \in SO(3)$: Rotationsmatrix (3×3)
  • $t \in \mathbb{R}^3$: Translation

In homogenen Koordinaten:

$$ \begin{pmatrix} X \\ Y \\ Z \end{pmatrix} = \begin{pmatrix} R & t \end{pmatrix} \begin{pmatrix} X_w \\ Y_w \\ Z_w \\ 1 \end{pmatrix} $$

1.2 Projektion in den Normalraum

Pinhole-Modell: Die Bildebene liegt bei $Z = 1$ vor der Kamera.

Ein 3D-Punkt im Kameraraum $X_c = (X, Y, Z)^T$ wird projiziert zu:

$$ x_n = \frac{X}{Z}, \qquad y_n = \frac{Y}{Z} $$

$(x_n, y_n)$ nennt man normierte Bildkoordinaten (Normalraum).

Bildlich: Vom Kamerazentrum aus geht ein Strahl durch den Punkt $(X,Y,Z)$ und schneidet die Ebene $Z=1$. Dieser Schnittpunkt hat die Koordinaten $(x_n, y_n, 1)$.

1.3 Intrinsische Matrix $K$: von Normalraum zu Pixeln

Der Sensor hat Pixel, also skalieren wir in Pixelkoordinaten. Die intrinsische Matrix ist:

$$ K = \begin{pmatrix} f_x & 0 & c_x \\ 0 & f_y & c_y \\ 0 & 0 & 1 \end{pmatrix} $$

mit

  • $f_x, f_y$: Brennweiten in Pixeln (Skalierung in $x$- und $y$-Richtung)
  • $c_x, c_y$: Principal Point (typischerweise die Bildmitte)

Übergang zu Pixeln:

$$ \begin{pmatrix} u \\ v \\ 1 \end{pmatrix} = K \begin{pmatrix} x_n \\ y_n \\ 1 \end{pmatrix} = \begin{pmatrix} f_x x_n + c_x \\ f_y y_n + c_y \\ 1 \end{pmatrix} $$

Also ganz konkret:

$$ u = f_x x_n + c_x, \qquad v = f_y y_n + c_y $$

1.4 Gesamtprojektionsmatrix $P$

Die komplette Kette Welt → Kamera → Normalraum → Pixel kann als eine 3×4-Matrix geschrieben werden:

$$ \lambda \begin{pmatrix} u \\ v \\ 1 \end{pmatrix} = K [R \mid t] \begin{pmatrix} X_w \\ Y_w \\ Z_w \\ 1 \end{pmatrix} = P \begin{pmatrix} X_w \\ Y_w \\ Z_w \\ 1 \end{pmatrix} $$

mit

$$ P = K [R \mid t] \in \mathbb{R}^{3 \times 4} $$

$\lambda$ ist ein homogener Skalierungsfaktor. Nach der Multiplikation normieren wir:

$$ (u, v, 1)^T = \frac{1}{w'} (u', v', w')^T = \frac{1}{w'} \, P \, \begin{pmatrix} X_w \\ Y_w \\ Z_w \\ 1 \end{pmatrix} $$

1.5 Beispielprojektion

Gegeben:

  • Bildgröße: $1920 \times 1080$
  • $f_x = f_y = 1000$
  • $c_x = 960,\; c_y = 540$ (Bildmitte)
  • Keine Rotation/Translation: $R = I,\; t = 0$

3D-Punkt:

$$ X = \begin{pmatrix} 1 \\ 1 \\ 5 \end{pmatrix} $$

Normierte Koordinaten:

$$ x_n = \frac{1}{5} = 0.2, \qquad y_n = \frac{1}{5} = 0.2 $$

Pixelprojektion:

$$ u = 1000 \cdot 0.2 + 960 = 1160 $$ $$ v = 1000 \cdot 0.2 + 540 = 740 $$

Ergebnis: Der Punkt erscheint bei Pixel $(1160, 740)$.


2. OpenCV-Kameramodell & Verzerrung

Reale Linsen sind nicht ideal. OpenCV modelliert typischerweise:

  • radiale Verzerrung: $k_1, k_2, k_3, \dots$
  • tangentiale Verzerrung: $p_1, p_2$

Ausgangspunkt sind die normierten Koordinaten $(x_n, y_n)$.

2.1 Radiale Verzerrung

Radius zum Bildzentrum:

$$ r^2 = x_n^2 + y_n^2 $$

Radial verzerrte Koordinaten:

$$ x_r = x_n \left(1 + k_1 r^2 + k_2 r^4 + k_3 r^6 + \dots \right) $$ $$ y_r = y_n \left(1 + k_1 r^2 + k_2 r^4 + k_3 r^6 + \dots \right) $$

Interpretation:

  • $k_1 > 0$: tonnenförmig (Ränder „nach außen“)
  • $k_1 < 0$: kissenförmig (Ränder „nach innen“)

2.2 Tangentiale Verzerrung

Wenn Linse/Sensor schief sitzt oder dezentriert ist:

$$ x_t = 2 p_1 x_n y_n + p_2 (r^2 + 2 x_n^2) $$ $$ y_t = p_1 (r^2 + 2 y_n^2) + 2 p_2 x_n y_n $$

Gesamtverzerrte Normalkoordinaten:

$$ \tilde{x} = x_r + x_t, \qquad \tilde{y} = y_r + y_t $$

Anschließend kommen wieder die Intrinsics:

$$ u = f_x \tilde{x} + c_x, \qquad v = f_y \tilde{y} + c_y $$


3. Undistortion – warum COLMAP das macht

Viele 3D-Pipelines (SfM, NeRF, Gaussian Splatting) arbeiten lieber mit einem einfachen Pinhole-Modell ohne Verzerrung. Deshalb:

  • Eingangsbilder sind verzerrt (OpenCV-Parameter $k_i, p_i$).
  • Wir erzeugen daraus „undistorted“ Bilder.
  • Die neuen Bilder haben ein reines Pinhole-Kameramodell.

3.1 Idee

  1. Für jeden Pixel im neuen undistorted Bild definiert man Normalkoordinaten $(x_n', y_n')$ mit einer neuen Matrix $K'$.
  2. Das Verzerrungsmodell wird rückwärts angewendet, um den dazugehörigen verzerrten Normalkoordinatenpunkt $(\tilde{x}, \tilde{y})$ im alten Modell zu finden.
  3. Mit der alten Matrix $K$ wird $(u_{\text{alt}}, v_{\text{alt}})$ berechnet.
  4. Farbwerte werden aus $(u_{\text{alt}}, v_{\text{alt}})$ entnommen (bilineare Interpolation) und nach $(u', v')$ im neuen Bild geschrieben.

Ergebnis:

  • Neue, undistorted Bilder
  • Neue Intrinsics $K'$ (ohne Verzerrung)
  • Kameramodell: z. B. PINHOLE oder SIMPLE_PINHOLE in COLMAP

4. Feature-Extraktion: von Pixeln zu Merkmalpunkten

Um 3D aufzubauen, brauchen wir Bildpunkte, die sich in vielen Bildern wiederfinden. Typischer Ansatz: SIFT.

4.1 SIFT ganz grob

  • Wir bauen einen Scale-Space: Bild $I(x,y)$ wird mit Gaußfiltern verschiedener $\sigma$ gefiltert.

$$ L(x,y,\sigma) = G(x,y,\sigma) * I(x,y) $$

$$ G(x,y,\sigma) = \frac{1}{2\pi\sigma^2} \exp\left( -\frac{x^2 + y^2}{2\sigma^2} \right) $$

  • Berechnung Difference-of-Gaussians (DoG):

$$ D(x,y,\sigma) = L(x,y,k\sigma) - L(x,y,\sigma) $$

Lokale Maxima/Minima in $(x,y,\sigma)$ sind SIFT-Keypoints.

Für jeden Keypoint:

  • Gradientenrichtung und -stärke bestimmen.
  • Ein Histogramm der Richtungen erstellen.
  • Einen 128-dimensionalen Deskriptor erzeugen. (4×4 Zellen × 8 Richtungsbins)

5. Feature-Matching zwischen Bildern

In Bild A gibt es Deskriptoren $d_i^A \in \mathbb{R}^{128}$ und in Bild B $d_j^B \in \mathbb{R}^{128}$.

Distanz:

$$ \mathrm{Dist}(d_i^A, d_j^B) = \lVert d_i^A - d_j^B \rVert_2 $$

Für jeden Deskriptor in A:

  1. Suchen wir die zwei nächsten Nachbarn in B.
  2. Nutzen den Lowe-Ratio-Test: $$ \frac{\lVert d_1 \rVert}{\lVert d_2 \rVert} < \tau $$ typischerweise $\tau \approx 0{,}7$–$0{,}8$.

So entstehen viele Punktkorrespondenzen

$$ x_i^A \leftrightarrow x_j^B, \quad x = (u, v, 1)^T. $$


6. Epipolargeometrie: Fundamentalmatrix und Essentialmatrix

6.1 Fundamentalmatrix $F$

Seien $x$ und $x'$ korrespondierende Pixelpunkte in zwei Bildern:

$$ x = \begin{pmatrix} u \\ v \\ 1 \end{pmatrix}, \quad x' = \begin{pmatrix} u' \\ v' \\ 1 \end{pmatrix} $$

Im idealen Fall gilt die Epipolargeometrie:

$$ x'^T F x = 0 $$

$F \in \mathbb{R}^{3 \times 3}$ hat Rang 2 und beschreibt die Beziehung zwischen den beiden Bildern ohne Intrinsics.

Zu einem Punkt $x$ in Bild 1 gehört in Bild 2 eine Epipolarlinie

$$ l' = F x $$

und der korrespondierende Punkt $x'$ muss auf $l'$ liegen:

$$ x'^T l' = 0. $$

6.1.1 Schätzung von $F$

  • Nutzung ausreichend vieler Punktpaare $x \leftrightarrow x'$.
  • 8-Punkt-Algorithmus oder 7-Punkt-Algorithmus.
  • RANSAC:
    • Ziehe zufällig 8 Korrespondenzen.
    • Schätze $F$.
    • Prüfe Epipolarfehler für alle Paare.
    • Wähle das $F$ mit den meisten Inliers.

6.2 Essentialmatrix $E$

Wenn Intrinsics $K, K'$ bekannt sind, normalisiert man die Bildpunkte:

$$ \hat{x} = K^{-1} x, \qquad \hat{x}' = K'^{-1} x' $$

Dann gilt:

$$ \hat{x}'^T E \hat{x} = 0 $$

mit

$$ E = K'^T F K $$

Struktur von $E$:

$$ E = [t]_\times R $$

  • $R$: Rotation von Kamera 1 zu Kamera 2
  • $t$: Translation (Richtung) zwischen Kamerazentren
  • $[t]_\times$: Kreuzprodukt-Matrix von $t$

7. Relative Kamerapose aus $E$

7.1 SVD von $E$

$$ E = U \Sigma V^T $$

Man erzwingt

$$ \Sigma = \mathrm{diag}(1, 1, 0) $$

Mit einer Hilfsmatrix

$$ W = \begin{pmatrix} 0 & -1 & 0 \\ 1 & 0 & 0 \\ 0 & 0 & 1 \end{pmatrix} $$

erhält man zwei Rotationen:

$$ R_1 = U W V^T, \qquad R_2 = U W^T V^T $$

Die Translation (bis auf Skala) ist

$$ t = U \begin{pmatrix} 0 \\ 0 \\ 1 \end{pmatrix} $$

Damit ergeben sich 4 mögliche Kombinationen:

  • $(R_1, \phantom{-}t)$
  • $(R_1, -t)$
  • $(R_2, \phantom{-}t)$
  • $(R_2, -t)$

Die richtige Kombination ist die, bei der die triangulierten 3D-Punkte vor beiden Kameras liegen ($Z > 0$ in beiden Kamerasystemen).


8. Triangulation eines 3D-Punktes (zwei Bilder)

Gegeben:

  • Projektionsmatrizen $P_1, P_2$
  • Pixelpunkte $$ x_1 = (u_1, v_1, 1)^T,\quad x_2 = (u_2, v_2, 1)^T $$

Gesucht: 3D-Punkt $X = (X, Y, Z, 1)^T$.

8.1 Lineares Gleichungssystem $AX = 0$

Man schreibt $P_i$ zeilenweise als

$$ P_i = \begin{pmatrix} p_{1,i}^T \\ p_{2,i}^T \\ p_{3,i}^T \end{pmatrix} $$

Aus $x_i \sim P_i X$ folgen zwei Gleichungen:

$$ (u_i p_{3,i}^T - p_{1,i}^T) X = 0 $$ $$ (v_i p_{3,i}^T - p_{2,i}^T) X = 0 $$

Für zwei Kameras erhält man 4 Zeilen → Matrix $A \in \mathbb{R}^{4 \times 4}$ mit

$$ A X = 0 $$

8.2 Lösung per SVD

$$ A = U \Sigma V^T $$

Gesucht ist der Vektor $X$, der zum kleinsten Singulärwert gehört → letzte Spalte von $V$.

Homogene Normierung:

$$ X = \begin{pmatrix} X \\ Y \\ Z \\ W \end{pmatrix} \;\Rightarrow\; \tilde{X} = \begin{pmatrix} X/W \\ Y/W \\ Z/W \end{pmatrix} $$

$\tilde{X}$ ist der kartesische 3D-Punkt.

8.3 Durchgerechnetes Beispiel (wie oben)

Intrinsics:

$$ K = \begin{pmatrix} 1000 & 0 & 960 \\ 0 & 1000 & 540 \\ 0 & 0 & 1 \end{pmatrix} $$

Kamera 1: $R_1 = I,\; t_1 = 0$

$$ P_1 = K [I \mid 0] $$

Kamera 2: um 1 m nach rechts verschoben

$$ C_2 = (1,0,0)^T,\quad t_2 = -C_2 = (-1,0,0)^T,\quad P_2 = K [I \mid t_2] $$

Wahrer 3D-Punkt:

$$ X_\text{true} = \begin{pmatrix} 2 \\ 1 \\ 5 \\ 1 \end{pmatrix} $$

Projektion in Kamera 1 führt zu $x_1 = (1160, 740, 1)^T$, in Kamera 2 zu $x_2 = (960, 740, 1)^T$.

Aufbau von $A$ mit diesen Werten und $P_1, P_2$ → SVD liefert

$$ X_\text{est} \approx (2, 1, 5, 1)^T $$

Der Fehler ist numerisch praktisch 0.

8.4 Einfluss von Pixelrauschen

Gemessene Pixel sind nicht perfekt:

$$ u_\text{mess} = u_\text{true} + \Delta u, \qquad v_\text{mess} = v_\text{true} + \Delta v $$

$$ \Delta u, \Delta v \sim \mathcal{N}(0, \sigma^2) $$

  • $\sigma = 0{,}5$ Pixel → Fehler oft im mm-Bereich
  • $\sigma = 2{,}0$ Pixel → Fehler leicht im cm-Bereich

Der Tiefenfehler hängt stark ab von:

  • Basislinie (Abstand der Kameras)
  • Entfernung des Punktes
  • Brennweite

9. Mehrere Bilder & Bundle Adjustment → sparse Cloud

9.1 Multi-View-Situation

Für jeden 3D-Punkt $X_j$ gibt es viele Beobachtungen:

$$ x_{ij} = \begin{pmatrix} u_{ij} \\ v_{ij} \end{pmatrix} $$

in Kamera $i$.

Pose der Kamera $i$:

$$ \theta_i = (R_i, t_i, K_i) $$

Projektionsfunktion:

$$ \pi(\theta_i, X_j) = \begin{pmatrix} u_{ij}^{\text{pred}} \\ v_{ij}^{\text{pred}} \end{pmatrix} $$

9.2 Reprojektionsfehler

Gemessener Pixel:

$$ x_{ij}^{\text{obs}} = \begin{pmatrix} u_{ij} \\ v_{ij} \end{pmatrix} $$

Fehler:

$$ e_{ij} = x_{ij}^{\text{obs}} - \pi(\theta_i, X_j) $$

9.3 Bundle Adjustment

Alle Kamera-Parameter $\{\theta_i\}$ und 3D-Punkte $\{X_j\}$ müssen optimiert werden:

$$ \min_{\{\theta_i\}, \{X_j\}} \sum_{i,j} \rho\left( \lVert e_{ij} \rVert^2 \right) $$

$\rho$ ist eine robuste Verlustfunktion (z. B. Huber), damit Ausreißer das Ergebnis nicht zerstören.

Das Problem wird typischerweise mit Levenberg-Marquardt und Schur-Komplement-Tricks gelöst (z. B. im Ceres Solver).

Ergebnis:

  • optimierte Kameraposen
  • optimierte 3D-Punkte

Das ist die sparse Point Cloud, die man am Ende sieht.


10. Unterschiedliche Inputs: Fotos vs. Video

10.1 Fotos

  • hohe Auflösung (z. B. 6000×4000)
  • RAW oder wenig Kompression
  • weniger Rauschen, gute Schärfe
  • sehr gute Feature-Detektion & -Matching

10.2 Video-Frames

  • oft nur 1920×1080 oder weniger
  • H.264/H.265-Kompression → Blockartefakte
  • Motion Blur, Rolling Shutter
  • viele sehr ähnliche Frames (redundant)

Folge:

  • weniger stabile Features
  • mehr Rauschen in Pixelpositionen
  • größere Triangulationsfehler

Deshalb machen viele Pipelines bei Video:

  • Frame-Subsampling (z. B. jedes 5. Frame)
  • Keyframe-Selektion
  • Schärfe-/Qualitätsfilter

11. Mehr Bilder – was passiert mit der Qualität?

  • 2 Bilder → minimale Information für Triangulation
  • Viele Bilder → Fehler mitteln sich
  • Große Baseline → gute Tiefenauflösung
  • Viele Beobachtungen → robuste und präzise 3D-Punkte

Geometrisch schneiden sich die Projektionsstrahlen aller Kameras nicht perfekt (wegen Rauschen). Bundle Adjustment sucht den 3D-Punkt, der zu allen Beobachtungen am besten passt → der „Fehlerkegel“ wird kleiner.


12. Die komplette Pipeline in Worten

  1. Man nimmt Bilder mit einer Kamera auf (Fotos oder Video-Frames).
  2. Kalibrierung der Intrinsics $K$ und das Verzerrungsmodell.
  3. Undistortion der Bilder → reines Pinhole-Modell.
  4. Für jedes Bild werden Features (z. B. SIFT) und Deskriptoren extrahiert.
  5. Feature matching zwischen Bildern um Korrespondenzen zu erhalten.
  6. Schätzung der Fundamentalmatrix $F$ und Entfernung der Ausreißer (RANSAC).
  7. Mit $F$ und $K$ berechnet man die Essentialmatrix $E$ und daraus die relative Pose $(R,t)$.
  8. Fixierung einer Referenzkamera mit $[I \mid 0]$ und bestimmst Posen für weitere Kameras.
  9. Triangulation der 3D-Punkte aus den 2D-Korrespondenzen (linear/nichtlinear).
  10. Bundle Adjustment für alle Kameras und Punkte.

Am Ende bekommst du:

  • optimierte Kamera-Posen und Intrinsics
  • eine sparsche 3D-Punktwolke – die Basis für dichte Rekonstruktionen, NeRFs, Gaussian Splatting & Co.
X: 0.00
Y: 0.00