Jacobian for Bundle Adjustment
Implement a Jacobian matrix computation for bundle adjustment optimization, a crucial step in image alignment and stitching. This process involves minimizing the reprojection error between observed and predicted image points.
Bundle adjustment is a non-linear least squares problem, where the goal is to find the optimal camera parameters and 3D point coordinates that minimize the reprojection error. The error is typically measured as the sum of squared differences between observed image points xij​ and predicted points π(Cj​,Pi​), where π is the projection function, Cj​ represents the camera parameters, and Pi​ represents the 3D point coordinates.
To compute the Jacobian matrix, we need to calculate the partial derivatives of the projection function with respect to the camera parameters and 3D point coordinates.
- Compute the partial derivatives of the projection function π with respect to the camera parameters Cj​.
- Compute the partial derivatives of the projection function π with respect to the 3D point coordinates Pi​.
This technique is widely used in structure from motion and stereo vision applications.
Example:
camera = [500, 500, 320, 240, 0, 0, 0, 0, 0, 5] point = [0, 0, 5]
2×13 Jacobian matrix
Jacobian has derivatives of projected (u,v) w.r.t:
- Intrinsics (fx, fy, cx, cy)
- Rotation (rx, ry, rz)
- Translation (tx, ty, tz)
- 3D point (X, Y, Z)
Computed via chain rule through projection.
Constraints:
- camera: Camera parameters [fx, fy, cx, cy, rx, ry, rz, tx, ty, tz]
- point: 3D point [X, Y, Z]
- Return: 2×13 Jacobian [d(u,v)/d(camera, point)]
More from CV: Image Alignment and Stitching
Bundle adjustment is a nonlinear least squares problem where you optimize camera parameters and 3D point positions to minimize reprojection error across all images and points. The projection function π(Cj​,Pi​) is nonlinear because it involves camera pose (rotation, translation), intrinsics, and a perspective divide, so you linearize it using a Jacobian and solve iteratively (e.g., with Gauss–Newton or Levenberg–Marquardt). The Jacobian encodes how each residual (2D reprojection error) changes with respect to each parameter (camera and point).
In practice, the Jacobian for bundle adjustment is very sparse and structured: each 2D observation only depends on one camera and one 3D point, so that residual row has nonzero entries only in the columns for that camera’s parameters and that point’s coordinates. This structure is crucial for efficiency and is what your problem is asking you to exploit: for each observation (i,j), compute the partial derivatives of the projection with respect to Cj​ and Pi​, and place them into the right block locations in J.
1. Background Knowledge (key concepts)
- Projection model Typically:
- Transform point from world to camera coordinates: Xc​=Rj​Pi​+tj​
- Normalize: u=Xcx​/Xcz​,v=Xcy​/Xcz​
- Apply intrinsics (for a pinhole camera):
The exact form depends on your parameterization (are intrinsics fixed? any distortion?).
- Residuals and Jacobian blocks For each observed 2D point xij​, residual is rij​=π(Cj​,Pi​)−xij​∈R2 The Jacobian row block for this residual w.r.t. all parameters is
\frac{\partial u}{\partial X_c} = \begin{bmatrix} 1/Z & 0 & -X/Z^2 \end{bmatrix},\quad \frac{\partial v}{\partial X_c} = \begin{bmatrix} 0 & 1/Z & -Y/Z^2 \end{bmatrix}
−Then:\frac{\partial \pi}{\partial X_c} = \begin{bmatrix} f_x \frac{\partial u}{\partial X_c} \ f_y \frac{\partial v}{\partial X_c} \end{bmatrix} \in \mathbb{R}^{2\times 3}
4. **Derivatives w.r.t. 3D point $P_i$** - $X_c = R_j P_i + t_j$ so:\frac{\partial X_c}{\partial P_i} = R_j
−Chainrule:\frac{\partial \pi}{\partial P_i} = \frac{\partial \pi}{\partial X_c} \frac{\partial X_c}{\partial P_i} = \left(\frac{\partial \pi}{\partial X_c}\right) R_j
- This gives a 2×3 block for point $i$. 5. **Derivatives w.r.t. camera pose $C_j$** - Translation:\frac{\partial X_c}{\partial t_j} = I_{3\times 3} \Rightarrow \frac{\partial \pi}{\partial t_j} = \frac{\partial \pi}{\partial X_c} I = \frac{\partial \pi}{\partial X_c}
- Rotation (Rodrigues): - $X_c = R(r_j) P_i + t_j$. - Need $\partial X_c / \partial r_j$ (3×3). There is a standard closed-form expression for $\partial R / \partial r_k$; for this problem it is enough to know: - You can precompute **skew-symmetric matrix** $[P_i]_\times$. - Locally, a small rotation increment $\delta\omega$ gives $\delta X_c \approx -[X_c]_\times \,\delta\omega$. - So Jacobian w.r.t. rotation parameters often looks like:\frac{\partial X_c}{\partial \delta \omega} \approx -[X_c]_\times
−Then:\frac{\partial \pi}{\partial r_j} = \frac{\partial \pi}{\partial X_c} \frac{\partial X_c}{\partial r_j}
−Concatenate:\frac{\partial \pi}{\partial C_j} = \left[ \frac{\partial \pi}{\partial r_j} ;;; \frac{\partial \pi}{\partial t_j} \right]
- This gives a 2×(pose-dim) block. 6. **Assemble the global Jacobian** - For each observation $(i, j)$: - At rows $2k, 2k+1$ (for this residual): - Insert $\partial \pi / \partial C_j$ into columns for