The CARLA Coordinate System
A summary of CARLA Coordinate System (Global, Camera, Image).
Introduction
To project the location of a 3D vehicle $O_{world}=(x, y, z, 1)$ onto the 2D camera image $O_{image}=(u, v, w)$, we need to be familiar with the CARLA coordinate system.
$$O_{image} = K[R|t] O_{world}$$
- Global Coordinates: $O_{world}$ is available using the API vehicle.get_location();
- Extrinsic Matrix: $[R|t]$ is provided by the API camera.get_transform().get_inverse_matrix();
- Intrinsic Matrix: $K$ can be constructed from camera properties (w, h, fov).
Global Coordinate
CARLA is developed using the Unreal Engine, which uses a coordinate system of x-front , y-right , z-up (left-handed).
We can get the world location (x, y, z, 1) of a vehicle using the API vehicle.get_location()
.
1>> vehicle.get_location()
2<carla.libcarla.Location object at 0x0000020E1CF58A50>
3x: -110.14263153076172
4y: -7.242839813232422
5z: -0.005238113459199667
Extrinsinc Matrix
The extrinsic matrix calculates the position of a vehicle relative to the camera.
$$O_{camera} = [R|t] O_{world}$$
1# Get the extrinsic matrix
2world_2_camera = np.array(camera.get_transform().get_inverse_matrix())
Intrinsic Matrix
We also need the intrinsic matrix K to project the relative position $O_{camera}$ to image coordinates $O_{camera} = (u, v, w)$.
$$O_{image} = K O_{camera}$$
Intrinsic Matrix:
$$ K = \begin{bmatrix} f & 0 & \frac{w}{2} \\ 0 & f & \frac{h}{2} \\ 0 & 0 & 1 \end{bmatrix} $$
1def build_projection_matrix(w, h, fov, is_behind_camera=False):
2 focal = w / (2.0 * np.tan(fov * np.pi / 360.0))
3 K = np.identity(3)
4
5 if is_behind_camera:
6 K[0, 0] = K[1, 1] = -focal
7 else:
8 K[0, 0] = K[1, 1] = focal
9
10 K[0, 2] = w / 2.0
11 K[1, 2] = h / 2.0
12 return K
Full Example:
Example 07: https://github.com/wuhanstudio/carla-tutorial
1def get_image_point(loc, K, w2c):
2 # Calculate 2D projection of 3D coordinate
3
4 # Format the input coordinate (loc is a carla.Position object)
5 point = np.array([loc.x, loc.y, loc.z, 1])
6 # transform to camera coordinates
7 point_camera = np.dot(w2c, point)
8
9 # New we must change from UE4's coordinate system to an "standard"
10 # (x, y ,z) -> (y, -z, x)
11 # and we remove the fourth componebonent also
12 point_camera = np.array(
13 [point_camera[1], -point_camera[2], point_camera[0]]).T
14
15 # now project 3D->2D using the camera matrix
16 point_img = np.dot(K, point_camera)
17
18 # normalize
19 point_img[0] /= point_img[2]
20 point_img[1] /= point_img[2]
21
22 return point_img