Inputs: world_point is a 3D point Xw=(10,5,20); intrinsic_lambda holds focal lengths fx=fy=1000 pixels and principal point (cx,cy)=(500,400); rotation_omega is the identity (camera axes match world axes); translation_tau =(0,0,5) shifts points 5 units along the optical axis.
World → camera:Xc=RXw+t=(10,5,20)+(0,0,5)=(10,5,25). The translation pushes the point farther from the camera, from depth 20 to depth 25.
Camera → image: applying K gives x′=(1000⋅10+500⋅25,1000⋅5+400⋅25,25)=(22500,15000,25), so w′=25 is the depth.
The pinhole camera model is the foundational geometric model in computer vision for projecting 3D world points onto a 2D image plane, assuming light rays pass through a single point (pinhole) without distortion. It separates intrinsic parameters (internal camera properties) and extrinsic parameters (camera pose in world space).
Intrinsic matrix K (3×3):
K=fx000fy0cxcy1
where fx,fy are focal lengths in pixels, and cx,cy is the principal point.
Extrinsic parameters: R (3×3 rotation matrix, world-to-camera) and t (3×1 translation vector).
Homogeneous coordinates: World point Xw=[X,Y,Z,1]T, projected to image point x′=[x′,y′,w′]T, then normalized to [u,v]=[x′/w′,y′/w′].
This model assumes perspective projection where parallel lines converge, valid for standard cameras but extended in variants like fisheye.
2. Algorithm Approach
The standard algorithm computes the projection matrix P=K[R∣t] (3×4), then applies linear transformation followed by perspective division:
Form extrinsic matrix: [R∣t] by concatenating R (columns 1-3) and t (column 4).
P=K⋅[R∣t].
x′=P⋅Xw.
u=x′/w′, v=y′/w′.
Matrix multiplication is O(1) for fixed 3×4×4 dimensions. Libraries like NumPy (Python) or Eigen (C++) handle this efficiently. No iterative optimization needed due to closed-form nature.
3. Step-by-Step Strategy
import numpy as np
def project_point(K, R, t, Xw):
# Step 1: Form extrinsic matrix [R | t] (3x4)
extrinsic = np.hstack((R, t.reshape(3, 1)))
# Step 2: Compute projection matrix P = K @ extrinsic (3x4)
P = K @ extrinsic
# Step 3: Project homogeneous point (4x1)
x_prime = P @ Xw # [x', y', w']
# Step 4: Perspective division and round to 4 decimals
u = x_prime / x_prime
v = x_prime / x_prime
return np.round([u, v], 4)
Input assumptions: K ("Lambda"), R ("Omega"), t ("Tau"), Xw as 4×1 vector. Constraints guarantee w′=0.
4. Common Pitfalls
Homogeneous coordinates: Forgetting to append 1 to Xw=[X,Y,Z].
Matrix dimensions: K (3×3) × [R∣t] (3×4) → P (3×4); P × Xw (4×1) → 3×1. Shape mismatches cause errors.
Perspective division: Dividing by zero (prevented by constraints); use w′ not z.
Rounding: Problem specifies 4 decimal places (not 2 as initially stated); use np.round(..., 4).
Coordinate systems: R transforms world-to-camera; verify convention (row-major vs column-major).
Floating-point precision: Use double precision; small numerical errors amplify in division.