Perspective Projection with Intrinsics
Implement a perspective projection that maps 3D world points to 2D image coordinates using a camera's intrinsic matrix. This process is crucial in computer vision for understanding how 3D scenes are projected onto 2D images.
The intrinsic matrix, denoted as K, encapsulates the camera's internal parameters, including focal lengths (fx​, fy​) in pixels and the principal point (cx​, cy​), which represents the optical center of the camera. The intrinsic matrix K is given by K=​fx​00​0fy​0​cx​cy​1​​ To project a 3D point (X, Y, Z) to a 2D image point, the following steps are involved:
- Perform perspective division by dividing the X and Y coordinates by Z.
- Apply the intrinsic matrix K to the normalized coordinates. The projection equation can be represented as p=Kâ‹…[X/Z,Y/Z,1]T.
This technique is widely used in 3D reconstruction and image processing applications.
Example:
points_3d = [[0, 0, 10], [5, 5, 10]] K = [[500, 0, 320], [0, 500, 240], [0, 0, 1]]
[[320.0, 240.0], [570.0, 490.0]]
Point [0,0,10]:
- Normalized: [0/10, 0/10, 1] = [0, 0, 1]
- Projected: K @ [0,0,1]^T = [320, 240, 1]
- Pixel: [320, 240]
Point [5,5,10]:
- Normalized: [0.5, 0.5, 1]
- Projected: K @ [0.5,0.5,1]^T = [250+320, 250+240, 1] = [570, 490]
Constraints:
- points_3d: List of [X, Y, Z] world points
- K: 3×3 intrinsic matrix
- Return: List of [u, v] pixel coordinates
- Round to 2 decimal places
The task is to use the pinhole camera model with a known intrinsic matrix K to map 3D points (X,Y,Z) in camera coordinates to 2D pixel coordinates (u,v) on the image. Conceptually, this is just applying a 3×3 matrix and then doing a division by depth Z.
Below is the minimal theory and implementation strategy you need.
1. Background Knowledge (Key Concepts)
- Pinhole camera model A camera is modeled as a pinhole where 3D points project onto an image plane. In camera coordinates, a point (X,Y,Z) (with Z>0) projects to normalized image coordinates:
These are measured in units of focal length, not pixels.
- Camera intrinsics K The intrinsic matrix converts normalized camera coordinates (x,y,1) into pixel coordinates (u,v,1):
where:
- fx​,fy​: focal lengths in pixels (may differ due to pixel aspect ratio),
- cx​,cy​: principal point (optical center) in pixel coordinates. Projection:
- Homogeneous coordinates Often written as:
and then you get pixel coordinates by dividing:
u=w′u′​,v=w′v′​For this simple case, w′=Z.
2. Algorithm / Approach
For each 3D point in camera coordinates:
- Option A (explicit formula) Use:
- Option B (matrix form)
- Form homogeneous 3D vector Pc​=(X,Y,Z)T.
- Compute ph​=K\mathbf{P}c​=(u′,v′,w′)T.
- Get pixel coordinates: u=u′/w′, v=v′/w′.
In code, you typically use vectorized matrix multiplication (e.g., with NumPy) over all points.
3. Step-by-Step Strategy
- Read inputs
- Intrinsic parameters fx​,fy​,cx​,cy​.
- A list/array of 3D points (Xi​,Yi​,Zi​) in camera coordinates.
- Build the intrinsic matrix
import numpy as np
K = np.array([
[fx, 0, cx],
[0, fy, cy],
[0, 0, 1]
], dtype=float)
- Form homogeneous 3D points
- If you have an array P of shape (N, 3) with rows [X, Y, Z], you can use it directly for matrix multiplication with K transposed:
# P shape: (N, 3)
P = points_3d # [[X1, Y1, Z1],..., [XN, YN, ZN]]
- Apply projection
# p_h will be shape (N, 3), each row [u', v', w']
p_h = (K @ P.T).T
- Convert to pixel coordinates
u = p_h[:, 0] / p_h[:, 2]
v = p_h[:, 1] / p_h[:, 2]
pixels = np.stack([u, v], axis=1) # shape (N, 2)
- Return / output the 2D points Use pixels as your final 2D image coordinates.
4. Common Pitfalls
-
Division by zero or negative depth
-
If Z≤0, the point is on or behind the camera plane; mathematically the projection breaks (or is undefined for Z=0).
-
In code, guard against Z=0 and decide how to handle such points (skip, mark invalid, etc.).
-
Mixing coordinate systems
-
This problem assumes (X,Y,Z) are already in camera coordinates.
-
Do not apply world-to-camera extrinsics here unless the problem explicitly asks for it.
-
Using K incorrectly
-
Ensure you multiply in the correct order: ph​=K\mathbf{P}c​, not Pc​K.
-
Check shapes: K is 3×3, points as 3×N or N×3 and transpose appropriately.
-
Forgetting to normalize
-
After matrix multiplication, you must divide the first two components by the third to get actual pixel coordinates.
5. Time & Space Complexity
Assume you have N 3D points:
-
Time complexity
-
Matrix multiplication K⋅PT is O(N) since K is constant size 3×3.
-
Normalization (division) is also O(N).
-
Overall: O(N).
-
Space complexity
-
You store the input points O(N) and the output pixel coordinates O(N).
-
The matrix K is constant size.
-
Overall: O(N).