Step 1
From depth to points
Turn every pixel of a depth image into a 3-D point in the world, see the cloud, and point at the tallest thing on the table.
A picture with distances
In Seeing with a Camera, a pixel only told you a direction, so you needed a known plane to find out how far away the ball was. The camera has been measuring that distance all along: img.depth is a 240 × 320 array of floats with one distance per pixel. It now shows in the Images tab next to the colour picture, light where things are near and dark blue where they are far.
Each value is , the distance along the camera's optical axis (not along the ray), in metres. Pixels that saw nothing at all hold inf.
Back-projection
Projection divides by depth: . With known, run it backwards. The pixel in column and row saw the point
in the camera's frame, where are the focal lengths and the principal point from . The camera pose (rotation , position ) moves it into the world: .
Every pixel at once
No loops: v, u = np.indices(depth.shape) gives every pixel's row and column, seen = np.isfinite(depth) masks out the misses, and u[seen] lists the columns of the pixels that saw something, row by row. Stack into an array. Rotating every row at once is points @ R.T, because each row becomes .
The result is a point cloud: about 77,000 points, one per pixel, that trace every surface the camera saw. viz.cloud(points, colour) draws one in the 3-D view.
Your task
Write depth_to_points(depth, K, T) so it returns an array of world points, one for every finite pixel, in row order.
The program keeps the points over the table, draws them, finds the highest one and moves the gripper 5 cm above it. The grader checks your function on a rendered depth image and a made-up camera, checks top, and checks where the gripper ends up.