#交通信号灯感知 这个文件描述百度阿波罗程序中得交通信号灯感知细节。
交通信号灯感知模块是设计用来通过摄像头提供精确可靠的交通信号灯状态。典型情况下,交通信号灯有三个状态,分别是红、黄、绿。有时候信号灯不工作会熄灭或者闪烁。偶尔情况下,因为信号灯不在摄像头视野中,所以我们的模块不能识别出它的状态。因此交通信号灯感知模块的输出有五种状态,分别是红,黄,绿,黑和未知。
我们模块会一开始反复查询hd地图来了解前方是否有信号灯。信号灯由它的边界四个点表示,可以通过给定车辆定位通过hd地图查询获得。前方信号灯被从世界坐标投射到图像坐标上。
考虑到信号灯的高度或者交叉路口的宽度的不同,固定视野的单摄像头,不能在超过100米的感知范围内看到信号灯。我们用多个摄像头扩大感知范围。在阿波罗2.0中,一个角度为25毫米的摄远镜头用来观测前方远处的信号灯。在摄远镜头里捕捉到的信号灯非常大也很容易识别。然而摄远镜头的视场非常有限,因此如果道路不是笔直的或者车辆靠近信号灯,信号灯经常在图像外。因此,需要安装一个焦距为6毫米的广角摄像头作为辅助视场。本模块会基于坐标投射自适应决定采用哪个摄像头。尽管只有两个摄像头在阿波罗车上,但是我们的算法可以处理多个摄像头。 流水线包含两个主要部分,预处理和处理。
因为信号灯状态变化的频率低,车载计算资源有限,所以没有必要每帧都探测信号灯。通常不同摄像头的图像会几乎同时到达,只有其中一个会进出处理阶段。然而,摄像头的选择是有必要的。由hd地图上的信号灯边界的四个点表示它。一个典型的信号灯信息如下:
signal info:
id {
id: "xxx"
}
boundary {
point { x: ... y: ... z: ... }
point { x: ... y: ... z: ... }
point { x: ... y: ... z: ... }
point { x: ... y: ... z: ... }
}
输入:
-
图像来自不同的摄像头,通过订阅获取:
-
/apollo/sensor/camera/traffic/image_long
-
/apollo/sensor/camera/traffic/image_short
-
定位,通过订阅获取:
-
/tf
-
hd地图
-
校准结果
输出:
- 所选摄像头的图像
- 交通信号灯边界框从世界坐标投射到图像坐标
驾驶时,边界点投射到每个摄像头的图像坐标。同一个位置,越长的焦距,投射面积越大,更容易探测到。因此能看到所有信号灯的最长焦距的摄像头会被选中。如果信号灯不能被投射到所有摄像头,我们就简单选择长焦摄像头走完所有流水。带时间戳的所选摄像头id缓存在队列中,如下描述:
struct ImageLights {
CarPose pose;
CameraId camera_id;
double timestamp;
size_t num_signal;
... other ...
};
注意 目前为止,我们所需要的所有信息是定位,校准结果和hd地图。摄像头选择因为独立于图像内容,可以在任意时刻执行。当图像到达时候,我们执行选择只是因为这么做比较简单。另外,摄像头选择不需要每帧都执行,我们设置了一个执行间隔时间。
图像到达时带有时间戳和摄像头id。一对时间戳和摄像头id用于查询对应的缓存信息。如果图像可以在缓存记录中找到一致的摄像头id和很小的时间戳误差,图像就能发布出去处理。所有不合适的图像会被抛弃。
我们将处理任务分成以下三个步骤。
输入:
- 来自于所选摄像头的图像
- 一组信号灯边框
输出:
- 一组带颜色标签的边框
投射位置会收到校准,定位和hd地图标签影响,因此并不完全可靠。 用投射的信号灯位置计算出一个更大的关注区域(ROI)用来发现精确的信号灯边界框。如下图所示,蓝色的长方体表示投射的信号灯边界框,离开实际信号灯很远。大的黄色长方体是ROI。
信号灯探测任务采用的是常规的CNN(卷积神经网络)探测,输入一张带ROI的图像,输出一系列边框。可能有输入信号灯外的多个信号灯在ROI内,我们需要根据探测评分,输入的信号灯位置和形状,选择适当的信号灯。如果CNN网络不能在ROI内找到任何信号灯,所有输入的信号灯状态会被标记为未知,剩下的步骤就会被跳过。
信号灯识别任务采用的是典型的CNN分类。神经网络接收到一张带有ROI和一组边界框的图像作为输入。输出的网络是一个4x_n_的向量。代表每个框的四种状态几率(黑,红,黄,绿)。最大并且足够大的概率状态会被认定为信号灯的状态。否则信号灯状态将被判定为黑,意味着状态未知。
因为信号灯可能闪烁,或者遮挡,所以识别器可能难以正常工作。目前的状态可能不代表真实的状态,有必要用修整器来矫正状态。如果接收到一个确切的装填,比如说红或者绿,修正器就会保存并直接输出状态。如果接收到一个黑或者未知状态,修正器就会查询已经保存的地图。当这个信号灯在某个时间存在确定的状态,修正器就会输出这个保存的状态,否则黑或者未知状态就会输出。因为有时序,黄灯只存在于绿灯之后红灯之前。安全起见,任何红灯后的黄灯都会被重置成红灯,直到绿灯亮起。