MOBILEYE: Headlight Taillight and Streetlight Detection
Reference:
本发明使用安装在移动车辆上的图像传感器,该传感器实时连续采集图像帧。在每一帧图像中,检测到一个足够亮的光斑。如果该光斑可以在随后的图像帧中匹配的上,该光斑和对应的光斑是同一物体。通过处理数据,可以对物体(或光斑)进行分类来产生一个物体分类。
数据通常与光斑和对应光斑的属性有关,如:图像中位置、形状、亮度、运动、颜色和空间一致。通过比较光斑和对应光斑各自在图像中的位置,跟踪光斑在图像空间中的运动。光斑可以利用径向基函数进行分类(前车灯、尾车灯、路灯、路牌)。优选地,利用光斑的纹理和/或边缘特征进行分类。
所述图像传感器优选地包括滤波器。该滤波器具有空间轮廓,例如棋盘格轮廓,包括优先传输红光的部分。将图像中的光斑与空间轮廓进行关联,对光斑进行分类。将目标分类为前车尾灯,确定与前车的距离,并根据该距离较好地自适应控制移动车辆的前灯。
Fig 5a:远处对向来车车头灯(100m+)具有近似径向对称的纹理,中心有一个明亮的点;
Fig 5b:近距离的大灯纹理,显示为四个簇;
Fig 5c:典型的包含非对称簇的路牌光斑,光斑亮度不均匀。
图示为路灯结构,三个及以上的光斑位于地平线以上,并沿着一条线接近道路的消失点,表示路灯结构。图中为两对两盏灯,图像的每边一个,被分类为路灯。
交通标识牌通常至少有一个清晰的边缘。
1. 算法结构
- 每个光斑包含如下结构体:
struct spot_struct
{
int id;
cv::Point2d last_xy;
std::vector<cv::Point2d> motion_history;
std::vector<int> shape_score_history;
std::vector<int> brightness_score_history;
int type; // oncoming, taillight, streetlight, untagged.
int age;
int approval_delay;
};
一个光斑通常以 type::untagged 开始。在它的生命周期内,光斑有可能被标记为 oncoming
、taillight
或 streetlight
。一旦一个光斑被标记为 oncoming 或 taillight,光斑会保持这个标签直到该光斑被杀死或重新评估光斑为另一个类别。比如,一个被标记为 streetlight 的光斑可能会被重新评估标记为 oncoming。
- 由于汽车尾灯在图像中经常以两个光斑的形式出现,因此有一个数据结构来保存可能的匹配对也是很有用的。每对包含以下信息:
struct pair_struct
{
cv::Point2d spot_1;
cv::Point2d spot_2;
std::vector<int> pair_scores_history;
std::vector<cv::Point2d> pair_motion_history;
int age;
int pair_not_found_grace;
int one_light_not_found_grace;
};
2. 算法流程
2.1 新图像中检测光斑流程
- 在图像中寻找高于一个阈值的局部最大值;
- 在图像空间中横向扩展光点,直到该区域下降到局部最大值的 90 % 90\% 90%,并确定光斑的大小和形状;
- 合并重合的光斑;
- 计算每个光斑的第零、一、二阶矩(即大小、位置、方位、近似椭圆的偏心率);
- 计算每个光斑的平均亮度和方差;
- 匹配旧的斑点到新的图像斑点:
- 基于之前的运动预测老光斑位置;
- 找到具有最相似的大小和亮度的最近似光斑(给定的预测运动)。将旧光斑与新光斑匹配的得分
S
S
S 可通过以下方法确定:
S = α ( x t − x t − 1 ) 2 + β ( y t − y t − 1 ) 2 + γ ( b t − b t − 1 ) 2 + δ ( s t − s t − 1 ) 2 S=\alpha\left(x_{t}-x_{t-1}\right)^{2}+\beta\left(y_{t}-y_{t-1}\right)^{2}+\gamma\left(b_{t}-b_{t-1}\right)^{2}+\delta\left(s_{t}-s_{t-1}\right)^{2} S=α(xt−xt−1)2+β(yt−yt−1)2+γ(bt−bt−1)2+δ(st−st−1)2
其中 ( x t , y t ) (x_t,y_t) (xt,yt), ( x t − 1 , y t − 1 ) (x_{t-1},y_{t-1}) (xt−1,yt−1) 分别为 t t t 时刻的光斑质心位置和从 t − 1 t-1 t−1 时刻预测的位置。 b b b 和 s s s 分别代表亮度值和大小值。 S S S 是结果分数; - 位置和大小都必须在给定的阈值内;
- 如果光斑的形状在前一个图像中表明两个前灯是接近的,在这一帧中光斑被允许从一个分裂成两个。例如,光点的形状可能在某一阈值以上被拉长,或者轮廓是非凸的。这种情况经常发生在迎面而来的车辆上。如果两个新光斑都给出很高的分数,并且没有一个与另一个旧光斑相匹配,那么旧光斑就会与两个新光斑相匹配;
- 一个不匹配的光斑保持存活 N N N 帧;
- 匹配旧光斑到两个新的图像光斑:
- 对于每一对,寻找两个最可能的光斑。
- 如果没有找到光斑对,则在阈值范围内找到最佳的单光斑匹配,并假设其他光斑没有相对移动但被遮挡。保持一段时间的帧数存活。
- 如果两个光斑都不匹配,保持 N N N 帧相同运动的存活。
- 对于匹配光斑,在原有的数据结构上增加新的光斑数据。对于不匹配的新光斑,创建新的数据结构;
- 在过去 N N N 帧中未被检测到的不匹配的老光斑被杀死(即从列表中删除)。
2.2 对向来车分类
- 使用对向来车的分类器路径测试图像中某行以下未作标记的光斑:
- 如果点有 N N N 个像素超过阈值 T T T,则标记点为对向来车;
- 计算光斑分类器得分;
- 计算结构对称得分;
- 计算纵向边缘得分;
- 计算边缘评分—如果检测到较大的边缘比率,则将光斑的“确认延迟”值增加 N N N;
- 测试在“确认延迟”状态下为对向来车方式:
- 如果光斑的 age 大于 10 + 10+ 10+ 的“确认延迟”状态,那么如果最后 10 10 10 帧的所有分数都大于 T 1 T1 T1,那么标记斑点为对向来车。
- 如果光斑的 age 大于 20 + 20+ 20+ 的“确认延迟”状态,那么如果最后 20 20 20 帧的所有分数都大于 T 2 T2 T2,那么标记斑点为对向来车。
- 如果光斑的 age 大于 40 + 40+ 40+ 的“确认延迟”状态,那么如果最后 40 40 40 帧的所有分数都大于 T 3 T3 T3,那么标记斑点为对向来车。
- 如果光斑的 age 大于 80 + 80+ 80+ 的“确认延迟”状态,那么如果最后 80 80 80 帧的所有分数都大于 T 4 T4 T4,那么标记斑点为对向来车。
其中 T 1 > T 2 > T 3 > T 4 T1>T2>T3>T4 T1>T2>T3>T4。
2.3 路灯或尾灯分类
- 测试图像中某行上方(与前面的某一行是同一行?)未标记的光斑,来验证路灯:
- 计算光斑分类器得分;
- 抛弃分数低于阈值的光斑;
- 如果三个或三个以上的光斑组成一条线经过道路的消失点附近,所有这些光斑都被标为为路灯;
- 如果两对这样的光斑在道路消失点附近形成两条相交的线,则标记四个光斑为路灯。
- 用尾灯分类器对未标记的光斑和光斑对进行分类:
- 向图像内运动测试(通过一个分数)。如果通过,则标记为尾灯;
- 计算尾灯 RBF 得分:如果最后 10 10 10 个分数高于阈值 T 1 T1 T1,则标记为尾灯;
- 如果斑点是一对的一部分,而且 age 大于 N N N,两个光斑都是可见的,这个框架,两个斑点的尾灯 RBF 分数都高于阈值 T 2 T2 T2,那么标记为尾灯。
2.4 灯光控制策略
- 如果对向来车的光斑存在并且它们都离开了场景,将光照计数器设置为一个小值(接近零)。如果对象来车光斑存在,并且至少有一个没有离开场景,将光照计数器设置为一个较大的值。如果没有对象来车光斑存在,减少光照计数器;
- 如果尾灯光斑存在,设置一个光照计数器到给定值。如果没有尾灯光斑存在,减少尾灯的光照计数器。
- 如果路灯光斑存在,设置一个光照计数器到给定值。如果没有路灯光斑存在,减少尾灯的光照计数器。
- 如果任何光照计数器大于零,不会切换至大灯。