【三维目标检测模型】ImVoteNet

 【版权声明】
本文为博主原创文章,未经博主允许严禁转载,我们会定期进行侵权检索。   

参考书籍:《人工智能点云处理及深度学习算法》

 本文为专栏《Python三维点云实战宝典》系列文章,专栏介绍地址“https://blog.csdn.net/suiyingy/article/details/124017716”。配套书籍《人工智能点云处理及深度学习算法》提供更加全面和系统的解析。

        ImVoteNet是一种基于VoteNet结构的多模态融合三维目标检测模型,发表在CVPR 2020 《ImVoteNet: Boosting 3D Object Detection in Point Clouds with Image Votes》,论文地址为“https://arxiv.org/abs/2001.10692”。其模型核心在于将图像中的几何结构、语义和RGB纹理信息融合到点云投票特征当中,以此来提高三维目标检测精度。

1 总体结构

        ImVoteNet模型结构如下图所示,输入数据包括RGB图像和点云。从模型名称上看,该模型以VoteNet为基础,并且多模态信息融合发生在投票特征提取阶段。RGB图像在预测出目标的二维候选框之后,根据点云种子点的位置关系,计算出二维候选框的投票结果、语义分类和RGB纹理信息,维度为KxF’。模型在点云分支上同样预测了KxF投票特征。这里K表示种子点数量,F和F’表示投票特征维度。

图ImVoteNet模型结构

        投票特征提取后,模型分别针对两种单模态特征和一种多模态特征进行VoteNet后续操作,包括候选框聚合、结果预测和损失计算等。这里单模态特征是指图像和激光深度分别提取的投票特征,维度为Kx(3+F’)和Kx(3+F)。多模态特征是指二者拼接融合后的特征,维度为Kx(3+F+F’)。其中,3表示投票点空间坐标。模型总体损失函数包括了这三种计算结果的各自损失,其中单模态损失权重各占0.3,多模态损失权重占0.4。实际上,很多模型改进点会集中在增加对损失函数的约束上来进行,例如增加面或棱的预测损失等。

        ImVoteNet总体计算过程如下图所示。

图 ImVoteNet总体计算过程

2 二维候选框预测

        ImVoteNet采用了两阶段二维目标检测模型,输入图像数据维度为3x608x832。该两阶段检测结构主要包括主干网络、Neck、RPN Head、ROI Head和NMS等步骤,入口函数为self.extract_bboxes_2d(img, img_metas, bboxes_2d=bboxes_2d, **kwargs)。

        主干网络采用残差网络ResNet结构,提取4种不同尺度特征,分别为256x152x208、512x76x104、1024x38x52、2048x19x26。Neck层采用特征金字塔FPN结构,实现特征多尺度特征融合,融合特征通道数量均为256,并输出5种尺度特征,分别为256x152x208、256x76x104、256x38x52、256x19x26、256x10x13。

        每个特征图位置会产生三种不同尺寸anchor,并通过RPN Head预测候选框有无目标以及目标位置,并且每种尺度特征图分别进行计算。因此,目标有无得分预测结果rpn_cls_score维度为3x152x208、3x76x104、3x38x52、3x19x26和3x10x13。位置预测结果rpn_bbox_pred维度为12x152x208、12x76x104、12x38x52、12x19x26和12x10x13。根据预测得分和NMS非极大值抑制,最多筛选并保留最多前1000个得分最高的候选框。不同尺度特征图对应的候选框相互间不进行NMS操作,并且删除尺寸过小的候选框。RPN Head返回的候选框维度为1000x5,其中1000为候选框数量。5个特征维度依次为候选框左上角x坐标tl_x、左上角y坐标tl_y、右下角x坐标br_x、右下角y坐标br_y以及目标有无得分conf。RPN配置如下所示。

proposal_list = self.img_rpn_head.simple_test_rpn(x, img_metas)
RPNHead(
  (loss_cls): CrossEntropyLoss(avg_non_ignore=False)
  (loss_bbox): L1Loss()
  (rpn_conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
  (rpn_cls): Conv2d(256, 3, kernel_size=(1, 1), stride=(1, 1))
  (rpn_reg): Conv2d(256, 12, kernel_size=(1, 1), stride=(1, 1))
)

        ROI Head对候选框进行ROI Align操作后各个候选框特征图变换到相同尺度(1000x256x7x7),然后进一步进行特征提取,分别完成10个类别目标进行预测,包括二维预测框(tl_x,、tl_y、br_x、br_y,conf)和目标类别预测结果label。ROI关键参数如下所示。其中共享全连接层第一层的输入特征数量为12544,即候选框特征维度(256x7x7)。由于模型需要预测10个类别目标(加上背景工11类),且每个目标位置坐标由4个维度(背景不需要进行预测),因此分类和位置回归的全连接层输出特征数量分别为11和40。

rets = self.img_roi_head.simple_test(x, proposal_list, img_metas, rescale=False)#每个类别目标的预测结果,10xKx5,10个类别,K个目标,tl_x、tl_y、br_x、br_y,conf
rois = bbox2roi(proposals)#[batchid, tl_x, tl_y, br_x, br_y]
cls_score, bbox_pred = self.bbox_head(bbox_feats)#1000x11,1000x40
Shared2FCBBoxHead(
  (loss_cls): CrossEntropyLoss(avg_non_ignore=False)
  (loss_bbox): L1Loss()
  (fc_cls): Linear(in_features=1024, out_features=11, bias=True)
  (fc_reg): Linear(in_features=1024, out_features=40, bias=True)
  (shared_convs): ModuleList()
  (shared_fcs): ModuleList(
    (0): Linear(in_features=12544, out_features=1024, bias=True)
    (1): Linear(in_features=1024, out_features=1024, bias=True)
  )
  (cls_convs): ModuleList()
  (cls_fcs): ModuleList()
  (reg_convs): ModuleList()
  (reg_fcs): ModuleList()
  (relu): ReLU(inplace=True)
)
ret = torch.cat([ret, sem_class[:, None]], dim=-1)#Nx6,xyxyconfcls
inds = torch.argsort(ret[:, 4], descending=True)#按照置信度分数排序
ret = ret.index_select(0, inds)#按照置信度分数排序

        RO结果再次根据目标预测置信度和NMS操作后最多保留100个预测目标。预测结果即为ImVoteNet模型的二维预测框bboxes_2d,维度为Kx6。其中,K表示预测的二维目标数量,此处6个维度分别是tl_x、tl_y、br_x、br_y、conf和label。

3 点云种子点生成

        ImVoteNet点云输入维度为20000x4,即x、y、z、r。与VoteNet中的种子点提取方式相同,该模型仍然通过PointNet2SASSG来提取到1024个种子点及其特征与索引,特征维度为256x1024。种子点提取的入口函数为self.extract_pts_feat(points)。

seeds_3d, seed_3d_features, seed_indices = self.extract_pts_feat(points)#PointNet2SASSG,提取种子点坐标及其特征与索引,1024x3、256x1024、1024。

4 图像投票特征提取

        ImVoteNet的图像投票特征提取层为VoteFusion,入口函数为self.fusion_layer(img, bboxes_2d, seeds_3d, img_metas),主要包括几何、语义和纹理特征提取三部分。关键程序如下所示。

xyz_depth = apply_3d_transformation(seed_3d_depth, 'DEPTH', img_meta, reverse=True)#将点云坐标变换到原始数据上去,数据增强反向变换
depth2img = xyz_depth.new_tensor(img_meta['depth2img'])#深度到相机变换矩阵
uvz_origin = points_cam2img(xyz_depth, depth2img, True)#深度到图像坐标
z_cam = uvz_origin[..., 2]#相机坐标系下,Z轴距离
uv_origin = (uvz_origin[..., :2] - 1).round()#原始点云在图像中的坐标
bbox_expanded = bbox_2d_origin.view(1, bbox_num, -1).expand(seed_num, -1, -1)#1024xKx6,每个种子点所对应的原始候选框
seed_2d_in_bbox = seed_2d_in_bbox_x * seed_2d_in_bbox_y#在二维候选框内的种子点,1024xKx1
sem_cue = sem_cue.scatter(-1, bbox_expanded_cls.long(), bbox_expanded_conf)#语义,1024xKx10,候选框对应类别的置信度
delta_u = bbox_expanded_midx - seed_2d_expanded_x#二维候选框中心与2D种子点的距离,cp,1024xKx1
delta_v = bbox_expanded_midy - seed_2d_expanded_y#二维候选框中心与2D种子点的距离,cp,1024xKx1
imvote = torch.cat([delta_u, delta_v, torch.zeros_like(delta_v)], dim=-1).view(-1, 3)
imvote = imvote * z_cam.reshape(-1, 1)#将图像中偏差cp变换到相机坐标系偏差
imvote = imvote @ torch.inverse(depth2img.t())#将偏差反向变换到深度坐标系
imvote = apply_3d_transformation(imvote, 'DEPTH', img_meta, reverse=False)#应用数据增强,与模型输入数据保持一致
ray_angle = seed_3d_expanded + imvote#种子点加上投票偏移,伪3D投票结果,投票的目标中心C'
ray_angle /= torch.sqrt(torch.sum(ray_angle**2, -1) + EPS).unsqueeze(-1)#深度坐标系中与坐标轴的余弦值
xz = ray_angle[:, [0, 2]] / (ray_angle[:, [1]] + EPS) * seed_3d_expanded[:, [1]] - seed_3d_expanded[:, [0, 2]]#伪三维投票偏差
geo_cue = torch.cat([xz, ray_angle], dim=-1).view(seed_num, -1, 5)
two_cues = two_cues * seed_2d_in_bbox.float()#仅针对属于bbox内部的种子点进行特征提取
uv_flatten = uv_rescaled[:, 1].round() * img_shape[1] + uv_rescaled[:, 0].round()#投影坐标
uv_expanded = uv_flatten.unsqueeze(0).expand(3, -1).long()
txt_cue = torch.gather(img_flatten, dim=-1, index=uv_expanded)#为每个点赋予归一化RGB值,相当于点云和图像对齐
txt_cue = txt_cue.unsqueeze(1).expand(-1, self.max_imvote_per_pixel, -1).reshape(3, -1)
img_feature = torch.cat([two_cues, txt_cue], dim=0)

4.1 几何投票特征提取

        种子点坐标seeds_3d根据相机内外参数变换矩阵投影到图像平面上,得到种子点的图像坐标uv_origin。2D种子点与各个二维候选框中心的偏差记为delta_u和delta_v,对应下图中向量cp。在二维图像平面上,二维种子点p的投票目标为候选框中心c。在相机坐标系中经过,三维物体中心C与其在像平面的成像位置c的连线经过光心O。在这条连线上的点C’的成像位置均为c。那么,投票点在二维平面上预测了投票位置c,在三维空间对应的是一条直线,直线上的点用C’表示。向量cp反变换到深度坐标系后为向量CPCP加上种子点三维坐标即可得到C’的坐标,进而得到OC所在直线的角度ray angle。

图C C’

        在SUN RGB-D数据集的深度坐标系中,y方向为深度方向,对应相机坐标系的z方向。当C’深度确定时,那么它的位置就可以根据角度ray angle等比例确定,进而得到C的坐标。这里,模型有一个前提假设,即目标中心与种子点相近。这是因为二维投票点必须落在二维目标框内才考虑提取其图像特征。在物体离相机有一定距离的情况下并且深度尺寸有限,近似认为物体中心与其内部种子点的深度相等,即C和P的深度近似相等。C的投票位置与P坐标之差记为图像的伪三维投票偏差xz(2个维度)。其与角度ray angle(3个维度)共同组成图像的几何投票线索特征geo_cue,维度为1024xKx5。其中,K为二维目标预测个数。

4.2 语义投票特征提取

        另一方面,每个二维种子点会被赋予语义特征,语义特征与其所在二维预测框的类别预测相关,取值为类别置信度。模型共预测10个类别,每个二维框的预测维度为10,且取值不为0之处对应目标的类别置信度。因此,语义特征预测结果sem_cue维度为1024xKx10。

        几何与语义线索特征进行拼接并用二维候选框范围进行约束可得到新的特征two_cues,维度为1024xKx15。同一个种子点最多可预测3个目标,那么K限制为3,two_cues的特征维度为1024x3x15,即15x3072。

4.3 纹理投票特征提取

        二维种子点的投票特征为图像坐标系对应的像素特征txt_cue,即归一化RGB取值,维度为3x3072。

        图像投票特征img_feature提取最终由上述三部分特征拼接而成,维度为18x3072。程序中进一步为每个种子点仅分配一个预测特征,因此,img_features维度恢复到18x1024,并进一步通过如下MLP实现特征融合,维度为256x1024。该特征记为点云种子点对应的图像特征。

img_features = self.img_mlp(img_features)#256x1024
MLP(
  (mlp): Sequential(
    (layer0): ConvModule(
      (conv): Conv1d(18, 256, kernel_size=(1,), stride=(1,))
      (bn): BatchNorm1d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (activate): ReLU(inplace=True)
    )
    (layer1): ConvModule(
      (conv): Conv1d(256, 256, kernel_size=(1,), stride=(1,))
      (bn): BatchNorm1d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (activate): ReLU(inplace=True)
    )

5 VoteNet结果预测与损失计算

        经过上述步骤后,ImVoteNet的种子点特征由三种类型,即点云特征seed_3d_features(256x1024)、图像特征(256x1024)以及两者拼接融合后的特征fused_features(512x1024)。模型针对这三种类型特征分别进行VoteNet预测和损失计算,具体过程可参考前文关于VoteNet的详细介绍。

        ImVoteNet损失函数共包含三大部分,分别对应上述三种类型特征,每个部分包括投票损失、目标损失、语义损失、中心损失、方向分类损失、方向回归损失、尺寸分类损失和尺寸回归损失等8种组成。点云特征、图像特征和融合特征对应的权重分别为0.3、0.3、0.6,经过加权求和后得到总的损失combined_losses。

6 模型训练

        模型训练命令为“python tools/train.py configs/imvotenet/imvotenet_stage2_16x8_sunrgbd-3d-10class.py”,采用SUN RGB-D作为输入数据集。运行训练命令可得到如图所示训练结果。

【python三维深度学习】python三维点云从基础到深度学习_python3d点云从基础到深度学习-CSDN博客

【版权声明】
本文为博主原创文章,未经博主允许严禁转载,我们会定期进行侵权检索。  

更多python与C++技巧、三维算法、深度学习算法总结、大模型请关注我的博客,欢迎讨论与交流:https://blog.csdn.net/suiyingy,或”乐乐感知学堂“公众号。Python三维领域专业书籍推荐:《人工智能点云处理及深度学习算法》。

 本文为专栏《Python三维点云实战宝典》系列文章,专栏介绍地址“https://blog.csdn.net/suiyingy/article/details/124017716”。配套书籍《人工智能点云处理及深度学习算法》提供更加全面和系统的解析。 

  • 7
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Coding的叶子

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

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

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

打赏作者

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

抵扣说明:

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

余额充值