参考代码:conditional-lane-detection
1. 概述
介绍:这篇文章针对车道线问题提出一种使用Conditional-Conv完成车道线检测的方案,其灵感源自于SOLO-V1&V2与CondInst,将车道线不同实例的检测问题转换为了在求解其对应条件卷积所包涵的动态卷积参数问题,正是用这些对应的动态卷积参数去表示不同的车道线实例,这种思路与CondInst的构建原理最为相似。在这篇文章中除了用上述提到针对不同车道线实例的条件卷积之外,还通过row-wise车道线(点 )定位与对应offset预测的方式实现车道线(点)的确定和对应refinement工作 。针对车道线中存在弯曲与交叉的情况,文章还针对性只用Conv-LSTM网络(也就是文章中提到的RIM模块)去预测对应动态卷积参数,从而引入时序感知网络去增加对于特征图全局视角的感知,从而提升对于弯曲与交叉情况的适应能力。综合上述的改进点文章的方法就在一定程度上避免了segmentation-based、anchor-based、polygon-based方法中存在的一些局限问题。
下图展示了文章的方法在一些case下的适应能力,可以看到文章的方法在弯曲交叉的情况也能表现出一定程度的适应性。
2. 方法设计
2.1 整体pipeline
文章的整体方法总结如下图所示:
在文章中为了增加网络的视觉感知能力增加了Transformer-Block到编码器中,然后在高层次的特征图上使用Proposal head生成用于车道线定位和偏移的动态卷积参数,最后在Conditional shape head中使用动态卷积参数实现对应车道线的预测。在上图中描述的是带有RIM模块的实现版本(对应代码为CondLaneRNNHead
),其实文章代码中还有一种直接在特征图上预测动态参数的实现版本(对应代码为CondLaneHead
)。
2.2 编码器中的Transformer-Block
在编码器的最后一个stage上文章为了增加特征的感知能力串联了几个transformer模块,其使用到的transformer模块的结构见下图所示:
在编码器中有无Transformer-Block模块对于整体性能的影响,见下表所示:
2.3 Proposal Head
这部分的工作是实现动态卷积参数的预测,用于后序模块完成车道线的预测,以及实现车道线起点heatmap的预测。完成动态卷积参数的预测在文章中给出了两种类型的实现方式:直接预测与Conv-LSTM增强感知。这两种方式在对应的场景上有所区别,一种是对应常规车道线,另外一种是对应存在扭曲交叉的情况。
PS:在对照文章代码的时候需要知道一些GT参数的具体含义用以帮助对代码的理解,可以参考这里的实现:
# mmdet/datasets/pipelines/lane_formating.py
2.3.1 直接预测
PS:这部分车道线预测是采用CondInst的策略完成的,在动态参数下估计车道线车道线在feature-map上的位置和该位置相对于实际位置(输入图像维度下)的偏移量。这部分的整体网络实现可以参考下面的这个类:
# mmdet/models/detectors/condlanenet.py#L199
class CondLaneNet(SingleStageDetector):
...
对应的网络预测头为:
# mmdet/models/dense_heads/condlanenet_head.py#L174
class CondLaneHead(nn.Module):
...
对于车道线heatmap的预测问题,文章分析了两种情况:使用车道线的中点(类似于CondInst)与使用车道线的起点,经过分析车道线在起点位置处的特征更加具有表征性,因而选择的是预测车道线的起点。之后再通过row-wise策略实现车道线的完成预测,只通过实例分割形式得到车道线在弯曲细长情况下会表现不好。
这里对起点heatmap的预测是通过focal loss实现的(heatmap包含的像素其label为1),其损失函数表达为:
L p o i n t = − 1 N p ∑ x y { ( 1 − P ^ x y ) α l o g ( P ^ x y ) P x y = 1 ( 1 − P x y ) β ( P ^ x y ) α l o g ( 1 − P ^ x y ) otherwise L_{point}=\frac{-1}{N_p}\sum_{xy} \begin{cases} (1-\hat{P}_{xy})^\alpha log(\hat{P}_{xy}) & \text{$P_{xy}=1$} \\ (1-P_{xy})^\beta (\hat{P}_{xy})^\alpha log(1-\hat{P}_{xy}) & \text{otherwise} \end{cases} Lpoint=Np−1xy∑{
(1−P^xy)αlog(P^xy)(1−Pxy)β(P^xy)αlog(1−P^xy)Pxy=1otherwise
heatmap与动态卷积参数的生成是通过下面的这个模块实现的:
# mmdet/models/dense_heads/ctnet_head.py#L29
class CtnetHead(nn.Module):
...
上述提到的车道线起点heat-map是直接在FPN输出特征图上使用上面提到的CtnetHead
模块完成对应的预测任务,之后得到heatmap和后序预测用的条件动态卷积参数,这部分代码可以参考:
# mmdet/models/dense_heads/condlanenet_head.py#L350
z = self.ctnet_head(f_hm) # 预测车道线的起点heatmap与动态参数
hm, params = z['hm'], z['params']
params = params.view(m_batchsize, self.num_classes, -1, h_hm, w_hm)
params = params.permute(0, 1, 3, 4, 2).contiguous().view(-1, self.num_gen_params)
# 得到车道线在特征图尺度下的像素定位
mask_params =