CrackRobotics

Step 1

The pinhole camera

Predict where a 3-D point shows up in the camera image, using the camera's pose and its intrinsics.

From positions to pixels

In Pick & Place, world.balls() handed you exact positions. Real robots have to see. A camera now stands at the far end of the table, facing the robot. camera.capture() returns an Image whose rgb is a 240 × 320 × 3 array of bytes. Pixel (u,v)(u, v) is column uu and row vv, so its colour is img.rgb[v, u].

Before a robot can find things in a picture, it has to know where things would appear. That's the pinhole model, and it has two steps.

1. Into the camera's frame

camera.pose is a 4 × 4 transform from camera to world coordinates. Its rotation RR = T[:3, :3] holds the camera's axes as columns, and tt = T[:3, 3] is the camera's position. Inverting it moves a world point pp into the camera frame:

pc=R⊤(p−t)p_c = R^\top (p - t)
Camera axisPoints
xxright in the image
yydown in the image
zzforward, out of the lens

2. Onto the image

The intrinsic matrix KK (camera.K) scales by the focal length ff, measured in pixels, and shifts by the principal point (cx,cy)(c_x, c_y):

λ[uv1]=K pc,K=[fx0cx0fycy001]\lambda \begin{bmatrix} u \\ v \\ 1 \end{bmatrix} = K\,p_c, \qquad K = \begin{bmatrix} f_x & 0 & c_x \\ 0 & f_y & c_y \\ 0 & 0 & 1 \end{bmatrix}

Dividing by the depth λ=zc\lambda = z_c gives u=fx xc/zc+cxu = f_x\,x_c / z_c + c_x and v=fy yc/zc+cyv = f_y\,y_c / z_c + c_y. That division is why distant things look small.

Your task

Implement project(p) so it returns np.array([u, v]). The starter captures an image and draws a white cross wherever project says each ball is. Open the Images tab: with a correct project, every cross sits on its ball.

The grader compares project with the real camera on 20 random points. Each must be within 0.5 px.

Goals

  • Program runs without errors
  • Took a picture with camera.capture()
  • project(p) matches the camera within 0.5 px (20 random points)
Loading physics…
Loading 3D view…
0.0 / 0.0 s

Python is loading. It takes a few seconds the first time.