v9.1.1
Menu

NeRF Ray Sampling

hardPRONeural 3D RepresentationsCVCV: 3D Reconstruction

Implement ray generation for Neural Radiance Fields (NeRF), a technique used to represent 3D scenes as continuous functions. This involves generating one ray for each pixel in an image, given camera parameters such as position and orientation.

The process relies on projective geometry, where each pixel's direction is calculated using the camera's intrinsic matrix KK and the pixel's coordinates. The ray origin is the camera position, while the ray direction points from the camera through the pixel.

Inputs

  • pose: a 4×44 \times 4 camera-to-world matrix (Rt0⊤1)\begin{pmatrix} R & \mathbf{t} \\ \mathbf{0}^\top & 1 \end{pmatrix}, where RR (3×33 \times 3) is the camera's rotation and t\mathbf{t} is the camera position in world coordinates.
  • K: the 3×33 \times 3 pinhole intrinsic matrix with focal lengths fx,fyf_x, f_y (diagonal) and principal point (cx,cy)(c_x, c_y) (last column).
  • img_size: a tuple (H,W)(H, W).

Key steps

  1. For the pixel in column uu and row vv, compute its camera-space direction. Use the NeRF (OpenGL) convention: the camera looks down −z-z and image yy points up:
dcam=(u−cxfx, −v−cyfy, −1)\mathbf{d}_{cam} = \left(\frac{u - c_x}{f_x},\ -\frac{v - c_y}{f_y},\ -1\right)
  1. Transform the direction by the camera's rotation: d=R dcam\mathbf{d} = R\,\mathbf{d}_{cam} (do not normalise it).
  2. The ray origin is t\mathbf{t} for every pixel.

Points along each ray, used later for volume rendering, then follow (you return only origins and directions, not the sampled points):

(xyz)=(xdydzd)t+(xoyozo)\begin{pmatrix} x \\ y \\ z \end{pmatrix} = \begin{pmatrix} x_d \\ y_d \\ z_d \end{pmatrix} t + \begin{pmatrix} x_o \\ y_o \\ z_o \end{pmatrix}

Output

Return a tuple (rays_o, rays_d) of two float arrays, each of shape (H⋅W,3)(H \cdot W, 3): one row per pixel in row-major order (row vv, column uu is row vW+uvW + u).

This technique is widely used in computer vision and 3D reconstruction applications.

Example

Input
Camera pose, K, image size
Output
Ray origins and directions
Reasoning
  • Inputs (the test case): pose is the 4×44 \times 4 identity, so R=IR = I and the camera sits at t=(0,0,0)\mathbf{t} = (0, 0, 0). K has fx=fy=500f_x = f_y = 500 and principal point (50,50)(50, 50). img_size is (100,100)(100, 100): 10,00010{,}000 pixels, so 10,00010{,}000 rays.
  • Top-left pixel (u=0,v=0u = 0, v = 0): (0−50500, −0−50500, −1)=(−0.1, 0.1, −1)\left(\frac{0-50}{500},\ -\frac{0-50}{500},\ -1\right) = (-0.1,\ 0.1,\ -1). Rotating by II changes nothing, so this is direction row 0.
  • Other pixels: (u,v)=(1,0)(u, v) = (1, 0) gives (−0.098, 0.1, −1)(-0.098,\ 0.1,\ -1) (row 1), so one column shifts xx by 0.0020.002. The centre (50,50)(50, 50) gives (0,0,−1)(0, 0, -1), straight down the optical axis; the bottom-right (99,99)(99, 99) gives (0.098, −0.098, −1)(0.098,\ -0.098,\ -1), row 99999999.
  • Origins: every row is t=(0,0,0)\mathbf{t} = (0, 0, 0). With translation (1,2,3)(1, 2, 3) every origin becomes (1,2,3)(1, 2, 3) and the directions stay the same.
  • Output: the ray origins and directions, two arrays of shape 10000×310000 \times 3, which is why the test prints (10000, 3). Notice the camera-space zz is always −1-1: directions are not unit length.

Constraints

  • Input parameters: camera pose (3D numpy array), intrinsic matrix K (3x3 numpy array), image size (2-element tuple of integers)
  • Valid ranges: camera pose and intrinsic matrix values are floating-point numbers, image size values are positive integers, pixel coordinates are in the range [0, image_size)
  • Output format: return ray origins and ray directions as two 2D numpy arrays of shape (H*W, 3): one row per pixel, row-major (e.g. (10000, 3) for a 100×100 image), both with floating-point precision
  • Special conditions: assume the input camera pose is in the format [x, y, z] and the intrinsic matrix K is in the standard pinhole camera format, with no lens distortion or other aberrations

Learn this in

More from CV: 3D Reconstruction

PRO

Editor locked

The code editor is locked for Pro problems. It is only available for free problems. Please upgrade to gain access to the code editor for all problems.

solution.py

Test results

Sign in to run your code against the test cases.