RESA车道线路沿检测

一、当前车道线检测遇到的问题

1、车道标注中固有的稀疏监督信号,使其一直很有挑战性

2、传统卷积不能很有效的提取细长的车道线和路沿(方格内有效特征很少),没有利用形状先验

3、SCNN提出在行列间传递信息,但是顺序信息传递是耗时的,相邻行列传递信息需要多次迭代,长距离传播容易丢失信息

解释:SCNN是切片,当前的i片特征经过一个[1,w]的卷积后再relu一下与i+1片相加作为新的i+1片,这样是逐个计算的,长距离传递容易丢失信息,比如到128条时,之前第一条传过来的信息已经淡化没了。

二、本论文提出的方法

1、提出RESA模块,利用车道的强形状先验,捕获行列间的空间关系

a.   采用并行方式传递信息,大大降低时间成本。

b.   信息以不同的步长传播,一个像素多次叠加另一个像素,防止长距离信息丢失同时使每个像素都能够收集全局信息。

c.    可以很方便的合并到其他网络

2、提出双边上采样解码器BUSD

一个分支用于捕获粗粒度特征upsample上采样算子采用双线性插值

一个分支用于捕获细粒度特征,转置卷积+两个non-bottleneck修复细微损失

可以将低分辨率特征精确的恢复为逐像素特征

三、模型结构

 编码层:ResNet或VGG

RESA层:

BUSD双边上采样层:

四、代码解析

class RESA(nn.Module):
    def __init__(self, cfg):
        super(RESA, self).__init__()
        self.iter = cfg.resa.iter  # 5
        chan = cfg.resa.input_channel  #channel层数128
        fea_stride = cfg.backbone.fea_stride  #骨干网络降采样倍数 8
        self.height = cfg.img_height // fea_stride # 得到特征图的长宽
        self.width = cfg.img_width // fea_stride
        self.alpha = cfg.resa.alpha  # 2
        conv_stride = cfg.resa.conv_stride #9
        #每个方向的卷积都要迭代iter次,初始化卷积
        for i in range(self.iter):
            #一行九列卷一下
            conv_vert1 = nn.Conv2d(
                chan, chan, (1, conv_stride),
                padding=(0, conv_stride//2), groups=1, bias=False)
            conv_vert2 = nn.Conv2d(
                chan, chan, (1, conv_stride),
                padding=(0, conv_stride//2), groups=1, bias=False)
            #setattr(object, name, value)用于设置属性值
            setattr(self, 'conv_d'+str(i), conv_vert1)
            setattr(self, 'conv_u'+str(i), conv_vert2)
            #九行一列卷一下
            conv_hori1 = nn.Conv2d(
                chan, chan, (conv_stride, 1),
                padding=(conv_stride//2, 0), groups=1, bias=False)
            conv_hori2 = nn.Conv2d(
                chan, chan, (conv_stride, 1),
                padding=(conv_stride//2, 0), groups=1, bias=False)

            setattr(self, 'conv_r'+str(i), conv_hori1)
            setattr(self, 'conv_l'+str(i), conv_hori2)
            #[1,2,3,4.......,31,0]
            #[2,3,4,5,......,0,1]
            #[4,5,6,7,......,2,3]
            #[8,9,10,.......,6,7]
            #得到并行计算的下标
            idx_d = (torch.arange(self.height) + self.height //
                     2**(self.iter - i)) % self.height
            setattr(self, 'idx_d'+str(i), idx_d)

            idx_u = (torch.arange(self.height) - self.height //
                     2**(self.iter - i)) % self.height
            setattr(self, 'idx_u'+str(i), idx_u)

            idx_r = (torch.arange(self.width) + self.width //
                     2**(self.iter - i)) % self.width
            setattr(self, 'idx_r'+str(i), idx_r)

            idx_l = (torch.arange(self.width) - self.width //
                     2**(self.iter - i)) % self.width
            setattr(self, 'idx_l'+str(i), idx_l)

    def forward(self, x):
        x = x.clone()

        for direction in ['d', 'u']:
            for i in range(self.iter):
                #获取对象属性
                conv = getattr(self, 'conv_' + direction + str(i))
                idx = getattr(self, 'idx_' + direction + str(i))
                #在一行九列上卷积,在行上相加,根据idx进行并行相加
                x.add_(self.alpha * F.relu(conv(x[..., idx, :])))

        for direction in ['r', 'l']:
            for i in range(self.iter):
                conv = getattr(self, 'conv_' + direction + str(i))
                idx = getattr(self, 'idx_' + direction + str(i))
                x.add_(self.alpha * F.relu(conv(x[..., idx])))

        return x

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CVplayer111

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值