v9.1.1
Menu

Jacobian for Bundle Adjustment

hardFREEBundle AdjustmentOptimizationCV: Image Alignment and Stitching

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 xijx_{ij} and predicted points π(Cj,Pi)\pi(C_j, P_i), where π\pi is the projection function, CjC_j represents the camera parameters, and PiP_i 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.

  1. Compute the partial derivatives of the projection function π\pi with respect to the camera parameters CjC_j.
  2. Compute the partial derivatives of the projection function π\pi with respect to the 3D point coordinates PiP_i.
E=∑i,j∥π(Cj,Pi)−xij∥2E = \sum_{i,j} \|\pi(C_j, P_i) - x_{ij}\|^2

Projection model

  • camera is [fx,fy,cx,cy,rx,ry,rz,tx,ty,tz][f_x, f_y, c_x, c_y, r_x, r_y, r_z, t_x, t_y, t_z], where r=(rx,ry,rz)r=(r_x,r_y,r_z) is an axis-angle (Rodrigues) rotation vector: rotation by angle θ=∥r∥\theta=\|r\| about the unit axis r/θr/\theta (identity when r=0r=0).
  • The point is moved into the camera frame with Pc=R(r) P+t=(Xc,Yc,Zc)P_c = R(r)\,P + t = (X_c, Y_c, Z_c) and projected with a pinhole model:
u=fxXcZc+cx,v=fyYcZc+cyu = f_x \frac{X_c}{Z_c} + c_x, \qquad v = f_y \frac{Y_c}{Z_c} + c_y
  • Return a 2×132 \times 13 array: row 0 holds the derivatives of uu, row 1 those of vv; columns 0–9 follow the order of camera, columns 10–12 are X,Y,ZX, Y, Z.

This technique is widely used in structure from motion and stereo vision applications.

Example

Input
camera = [500, 500, 320, 240, 0, 0, 0, 0, 0, 5]
point = [0, 0, 5]
Output
2×13 Jacobian matrix
Reasoning
  • camera holds fx=fy=500f_x=f_y=500, principal point (cx,cy)=(320,240)(c_x,c_y)=(320,240), zero rotation and translation t=(0,0,5)t=(0,0,5); point is P=(0,0,5)P=(0,0,5). Columns are the 10 camera parameters then X,Y,ZX,Y,Z; row 1 is uu, row 2 is vv.
  • With no rotation the camera-frame point is Pc=P+t=(0,0,10)P_c=P+t=(0,0,10), which lands exactly on the principal point: u=500⋅0/10+320=320u=500\cdot 0/10+320=320, v=240v=240.
  • Intrinsics: ∂u/∂cx=∂v/∂cy=1\partial u/\partial c_x=\partial v/\partial c_y=1, but ∂u/∂fx=Xc/Zc=0\partial u/\partial f_x=X_c/Z_c=0 — a point on the optical axis doesn't move when the focal length changes.
  • Translation and point: ∂u/∂tx=∂u/∂X=fx/Zc=50\partial u/\partial t_x=\partial u/\partial X=f_x/Z_c=50 and likewise ∂v/∂ty=∂v/∂Y=50\partial v/\partial t_y=\partial v/\partial Y=50; depth gives 0 because Xc=Yc=0X_c=Y_c=0.
  • Rotation: a tiny rotation δr\delta r moves PP by δr×P\delta r\times P, so about yy it shifts XcX_c by 5 δry5\,\delta r_y, giving ∂u/∂ry=500⋅5/10=250\partial u/\partial r_y=500\cdot 5/10=250; about xx it gives ∂v/∂rx=−250\partial v/\partial r_x=-250; about zz an on-axis point doesn't move.
  • So the 2×13 Jacobian matrix has row uu [0,0,1,0,0,250,0,50,0,0,50,0,0][0,0,1,0,0,250,0,50,0,0,50,0,0] and row vv [0,0,0,1,−250,0,0,0,50,0,0,50,0][0,0,0,1,-250,0,0,0,50,0,0,50,0]. Notice how sparse it is: off-axis points would fill in the fxf_x, rzr_z and depth columns.

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)]

Learn this in

More from CV: Image Alignment and Stitching

solution.py

Test results

Sign in to run your code against the test cases.