出于两种原因,有时候需要知道哪些车辆或行人在相机的视野范围内/不在视野范围内
- 利用Carla制作数据集时,不管是3D物体目标检测还是2D物体目标检测,我们都需要图片训练集。例如相机图片和图片内车辆或行人的ground truth(2d bbox, 3d bbox)。
- 可视化呈现。例如在V2V通信场景下,车辆之间是有通信的,那么可以将这种通信关系在相机图片上绘制出来,表达更直观。
上述两个例子我们都需要知道目标物体(车、人)是否在相机的视野范围内,例如生成车辆的3d bbox,只有在视野范围内的车辆才生成ground truth。
如何判断一个目标是否在视野范围内呢?只需要知道三个量:目标物体的世界坐标、相机外参数矩阵和相机内参数矩阵。
利用坐标变换,可以将目标物体的世界坐标转换为图片的二维坐标,具体步骤如下:
- carla中获取目标的世界坐标:
actor.get_transform().location
- 相机外参数矩阵:
camera.get_transform().get_matrix()
- 相机内参数矩阵:
k = np.identity(3)
k[0, 2] = WINDOW_WIDTH_HALF
k[1, 2] = WINDOW_HEIGHT_HALF
f = WINDOW_WIDTH / (2.0 * math.tan(90.0 * math.pi / 360.0))
k[0, 0] = k[1, 1] = f
- 利用相机外参矩阵求出目标在相机坐标系下的三维坐标:
def proj_to_camera(pos_vector, extrinsic_mat):
# transform the points to camera
transformed_3d_pos = np.dot(inv(extrinsic_mat), pos_vector)
return transformed_3d_pos
- 利用相机内参矩阵求将相机的三维坐标转换为图片内的二维坐标:
def proj_to_2d(camera_pos_vector, intrinsic_mat):
# transform the points to 2D
cords_x_y_z = camera_pos_vector[:3, :]
cords_y_minus_z_x = np.concatenate([cords_x_y_z[1, :], -cords_x_y_z[2, :], cords_x_y_z[0, :]])
pos2d = np.dot(intrinsic_mat, cords_y_minus_z_x)
# normalize the 2D points
pos2d = np.array([
pos2d[0] / pos2d[2],
pos2d[1] / pos2d[2],
pos2d[2]
])
return pos2d
- 判断车辆是否在相机视野内:
def point_in_top_view(pos):
"""Return true if point is in top view"""
if (pos[0] > 0) and (pos[0] < DISPLAY_HEIGHT) and (pos[1] > 0) and (pos[1] < DISPLAY_WIDTH):
return True
return False
这里这是目标的中心点,求3d bbox也是同样的方法,只不过是将八个点都转换一下。
另外,注意一点,在制作3d box 的ground truth时,不能光判断box的点是否在图像内,还要判断点是否被遮挡,这个可以以用carla的depth camera来辅助完成。
这篇博客是对前面有些没说清的地方的总结,具体代码可以参考:github
Carla的其他一些信息可以参考我之前写的博客