[BEV] 学习笔记之Lift, Splat, Shoot

在开源的BEV模型中,可以追溯到2020年nvidia开源的 Lift-Splat- Shoot这篇论文中,论文的核心是显示的估计图像的深度特征,并转化为BEV特征,作为BEV视角下的开山鼻祖,自然是要对原理以及代码进行阅读,本文将对关键代码进行注释。

项目地址:https://github.com/nv-tlabs/lift-splat-shoot
学习视频:手撕BEV的开山之作 lift, splat, shoot
欢迎正在学习或者想学的CV的同学进群一起讨论与学习,同时会有许多智驾内推机会,v群:Rex1586662742,q群:468713665

2、模型简介

LSS这篇论文主要的贡献在于提出LIFT,在视锥的条件下,显示的预测了每个特征点的离散距离,如下图所示。
在这里插入图片描述

3、前向推理

通过对推理的梳理,可以理解论文的思路,以及在代码中的实现,下面为foward的过程。
1、src/explore.py

def viz_model_preds(...):
    '''
    xbound=[-50.0, 50.0, 0.5], bev特征大小
    ybound=[-50.0, 50.0, 0.5],
    zbound=[-10.0, 10.0, 20.0], LSS论文中不计算物体的高度
    dbound=[4.0, 45.0, 1.0], 离散深度尺寸,间隔为1
    '''
    out = model(...)
    # 进入到/data/cv_demo/bev/lift-splat-shoot/src/models.py -> forward(...)

2、src/models.py

class LiftSplatShoot(...):
    def __init__(...):# 生成视锥
        self.frustum = self.create_frustum()
        # 图像特征提取
        self.camencode = CamEncode(self.D, self.camC, self.downsample)
        # bev特征提取
        self.bevencode = BevEncode(inC=self.camC, outC=outC)
        
    def create_frustum(...):
        # 原图高宽
        ogfH, ogfW = self.data_aug_conf['final_dim']
        # 特征图宽高
        fH, fW = ogfH // self.downsample, ogfW // self.downsample\
        # 距离 ds:[[41, 8, 22]]  每个特征点预测41个距离
        ds = ...
        # 视锥x坐标 xs:[41, 8, 22]
        xs  = ...
        # 视锥y坐标  xs:[41, 8, 22]
        ys = ...
        # 视锥点云 frustum:[41, 8, 22, 3]      
        frustum = torch.stack((xs, ys, ds), -1)
        
    def get_geometry(...):
        """
        param:rots, trans, intrins, post_rots, post_trans
        """
        # 视锥点云减去图像预处理的平移矩阵
        points = self.frustum - post_trans.view(B, N, 1, 1, 1, 3)
        # 视锥点云乘以图像与处理的旋转矩阵的逆矩阵
        points = torch.inverse(post_rots).view(B, N, 1, 1, 1, 3, 3).matmul(points.unsqueeze(-1))
        # 图像坐标系转相机坐标系,对应转化的公式
        # xs,ys,lamda
        # lamda * xs, lamda *ys, lamda 
        points = torch.cat((points[:, :, :, :, :, :2] * points[:, :, :, :, :, 2:3],
                            points[:, :, :, :, :, 2:3]
                            ), 5)
        # 相机坐标系转ego坐标系
        combine = rots.matmul(torch.inverse(intrins))
        points = combine.view(B, N, 1, 1, 1, 3, 3).matmul(points).squeeze(-1)
        points += trans.view(B, N, 1, 1, 1, 3)
        return points
        
    def get_cam_feats(...):
        """
        x:环视图片 [4, 6, 3, 128, 352]
        """
        # 图片深度特征提取 -> [24, 64, 41, 8, 22] 
        x = self.camencode(x)
        x = x.view(B, N, self.camC, self.D, imH//self.downsample, imW//self.downsample)
        # [4, 6, 41, 8, 22, 64]
        x = x.permute(0, 1, 3, 4, 5, 2)
        return x

    def voxel_pooling(...):
        """
        geom_feats:ego坐标系下的视锥点云 [4, 6, 41, 8, 22, 3]
        x:环视图像的特征  [4, 6, 41, 8, 22, 64]
        """
        Nprime = B*N*D*H*W # 视锥点的个数
        # x:[173184, 64]
        x = x.reshape(Nprime, C) 
        # 将视锥点云的坐标移动到 移动到BEV特征坐标的中心
        geom_feats = ((geom_feats - (self.bx - self.dx/2.)) / self.dx).long()
        # 所有视锥点的坐标 geom_feats:[173184, 3]
        geom_feats = geom_feats.view(Nprime, 3)
        # batch_ix:[173184, 1] [0,0,0,...,1,1,1,...,2,2,2] 记录每个点在那个batch内
        batch_ix = ...
        
        # 过滤不在bev空间下的点
        kept = ...
        x = x[kept]
        geom_feats = geom_feats[kept]
        # x,y,z,b  将多个相机中重合点排到一起
        # (x*200 + y * 1 + z * 1 + 1) * B
 		# 视锥点在BEV特征下的全局索引 最大为 200 * 200
        ranks = ...
        sorts = ranks.argsort()
        # 将xyz相同的点排到一起
        x, geom_feats, ranks = x[sorts], geom_feats[sorts], ranks[sorts]
        # rank中一样的值,只取最后一个
        # 例如rank为 [1,1,2,2,2,3,3,3,3,3]
        # 将其转化为 [0,1,0,0,1,0,0,0,0,1]然后将为1的点取出来
        if not self.use_quickcumsum:
            x, geom_feats = cumsum_trick(x, geom_feats, ranks)
        else:
            ...
        # final:[4, 64, 1, 200, 200]  bev 特征
        final = ...
        return final
        
    def get_voxels(...):
        geom = self.get_geometry(rots, trans, intrins, post_rots, post_trans)
        x = self.get_cam_feats(x)
        # x:[4, 64, 200, 200] bev特征
        x = self.voxel_pooling(geom, x)
        return x
        
    def forward(...):
        """
        x:imgs,环视图片  (bs, N, 3, H, W)
        rots:由相机坐标系->车身坐标系的旋转矩阵,rots = (bs, N, 3, 3)
        trans:由相机坐标系->车身坐标系的平移矩阵,trans=(bs, N, 3)
        intrins:相机内参,intrinsic = (bs, N, 3, 3)
        post_rots:由图像增强引起的旋转矩阵,post_rots = (bs, N, 3, 3)
        post_trans:由图像增强引起的平移矩阵,post_trans = (bs, N, 3)
        """
        x = self.get_voxels(x, rots, trans, intrins, post_rots, post_trans)
        # 卷积
        x = self.bevencode(x)
        return x 
# LIFT
class CamEncode(...):
    def __init__(...):
        self.D = D # 离散距离  41
        self.C = C # 特征维度  64
        # 图片特征提取
        self.trunk = ... 
        # 上采样模块
        self.up1 = ...
        # 深度特征提取网络
        self.depthnet = ...
    
    def get_depth_feat(...):
        # 使用efficientnet提取特征 x: 24 x 512 x 8 x 22
        x = self.get_eff_depth(x) 
        # 预测深度特征
        x = self.depthnet(x)
        # 深度
        depth = self.get_depth_dist(x[:, :self.D])
        # 深度特征
        new_x = ...
        return depth, new_x
# Splat
class BevEncode(...):
    def __init__(...):
        ...
    def forward(...)
        ...

3、src/tools.py

class SimpleLoss(torch.nn.Module):
    def __init__(self, pos_weight):
        super(SimpleLoss, self).__init__()
        # sigmoid+二值交叉熵损失
        self.loss_fn = torch.nn.BCEWithLogitsLoss(pos_weight=torch.Tensor([pos_weight]))

    def forward(self, ypred, ytgt):
        loss = self.loss_fn(ypred, ytgt)
        return loss
4、总结

以上为LSS算法实现的基本流程,如有错误,欢迎大家进行指正,后续还要学习其他BEV系列的模型,希望能对BEV模型有进一步的理解。

<think>好的,我现在需要帮助用户了解BEV(Bird's Eye View)相关的学习路径和资源。首先,我需要回顾用户提供的系统级指令和参考引用,确保回答符合格式和内容要求。 首先,用户提到必须使用中文回答,并且生成相关问题。同时,引用的站内资料需要正确标注。用户提供的引用[1]和[2]主要介绍了BEV的基本概念、应用领域以及当前面临的主要问题,如视角转换、特征融合等。 接下来,我需要构建一个结构清晰的学习路线。考虑到BEV涉及计算机视觉、深度学习、传感器融合等多个领域,学习路径应该从基础到高级逐步推进。可能需要分阶段,比如基础知识、核心算法、实践应用、高级专题等。 在基础知识部分,用户需要了解计算机视觉的基本概念,比如图像处理、特征提取,以及深度学习的基础,如CNN、Transformer。数学基础方面,线性代数、概率统计和3D几何也很重要。这部分可以推荐经典的教材和在线课程,比如《深度学习》和Andrew Ng的课程。 核心概念部分,需要详细解释BEV的定义、传感器数据转换(如相机、激光雷达)、视角转换的算法。这里可以结合引用[1]提到的BEV网络如何转换传感器数据,以及引用[2]中提到的视角重构问题。可能需要提到多视图几何、NeRF等技术。 在实践应用阶段,建议学习框架如PyTorch,参与开源项目如BEVFormer,并实践数据集如nuScenes。同时,可以推荐具体的论文和教程,比如Waymo的开放数据集和相关GitHub项目。 高级专题方面,引用[2]提到的特征融合、跨传感器标定、3D目标检测和动态场景处理都是关键点。需要引导用户阅读最新的论文和参与行业会议,保持对前沿技术的了解。 资源推荐部分,要包括课程、论文、代码库和社区。确保引用的资料权威且实用,比如CVPR教程和特斯拉的演讲。 最后,生成的相关问题需要围绕学习路线中的难点、应用优化、数据集比较和实际挑战展开,帮助用户深入思考。 检查是否需要使用正确的LaTeX格式,比如行内公式用$...$,独立公式用$$...$$,并确保没有语法错误。同时,引用标识要自然地添加在相关段落的末尾,如[^1][^2]。 总结整个思考过程,确保回答结构清晰,符合用户的要求,并且涵盖用户可能需要的各个方面,从理论到实践,逐步深入。</think>### BEV(Bird's Eye View)学习路线与资源指南 #### 一、基础知识准备 1. **计算机视觉基础** - 学习图像处理、特征提取、目标检测等基础概念,推荐课程如《计算机视觉:模型、学习和推理》。 - 掌握经典算法:卷积神经网络(CNN)、Transformer、多视角几何等。 - 数学基础:线性代数(矩阵变换)、概率统计、3D几何(如坐标系转换公式:$$P_{\text{BEV}} = T \cdot P_{\text{camera}}$$)。 2. **深度学习框架** - 熟练使用PyTorch或TensorFlow,建议通过官方教程和实战项目(如Kaggle竞赛)加深理解。 --- #### 二、BEV核心概念与技术 1. **BEV定义与传感器融合** - BEV的核心是将多传感器数据(相机、激光雷达、雷达)映射到俯视坐标系,需理解相机标定、点云处理(如激光雷达数据格式:$x, y, z, \text{intensity}$)。 - 学习视角转换算法,如IPM(逆透视变换)、NeRF(神经辐射场)等。 2. **特征提取与融合** - 研究多模态特征融合方法(如早期融合、晚期融合),重点关注BEVFormer等模型的设计思路。 - 掌握跨视图特征对齐技术(如可变形注意力机制)。 --- #### 三、实践与项目 1. **开源框架与工具** - 代码库: - [BEVFormer](https://github.com/fundamentalvision/BEVFormer)(基于多摄像头的BEV检测模型) - [LSS(Lift-Splat-Shoot)](https://github.com/nv-tlabs/lift-splat-shoot)(特斯拉采用的BEV生成方法) - 数据集: - nuScenes(多传感器标注数据) - Waymo Open Dataset(大规模自动驾驶场景) 2. **论文精读与复现** - 必读论文: - *"BEVDet: High-Performance Multi-Camera 3D Object Detection in Bird-Eye-View"* - *"Translating Images into Maps"*(IPM与深度学习的结合)[^2] - 复现经典模型(如BEVDepth),理解损失函数设计(如$L_{\text{bev}} = \alpha L_{\text{3D}} + \beta L_{\text{2D}}$)。 --- #### 四、高级专题与研究方向 1. **动态场景与时序建模** - 研究BEV中的运动预测(如轨迹生成算法:$s(t) = \int v(t) dt$)。 - 探索多帧BEV融合(如视频BEV感知)。 2. **泛化性与适配性优化** - 针对传感器参数变化(如相机焦距不同),学习领域自适应方法(如无监督域适应)。 --- #### 五、推荐学习资源 1. **课程与教程** - [MIT 6.869: Advances in Computer Vision](https://ocw.mit.edu/)(包含BEV相关专题) - [CVPR 2023 BEV感知教程](https://cvpr2023.thecvf.com/) 2. **社区与论坛** - arXiv最新论文(关键词:BEV Perception, Bird's Eye View) - 知乎专栏《自动驾驶中的BEV感知》 - 特斯拉AI日技术解读(BEV生成与Occupancy Networks) ---
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Rex晚枫

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

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

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

打赏作者

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

抵扣说明:

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

余额充值