3D⽬标检测算法详解_pointnet,pointnet++,frustum-pointn。。 。
知识点回顾高温锂基脂
。
点云包含了很多信息,除了3维坐标数据之外,还可能包括颜⾊、分类值、强度值、时间等。 点云数据可以由多种⽅法获得:1.直接由Lidar激光扫描出点云数据。 2.不同⾓度的2D图像组合成点云 3.,即将图像坐标+深度信息从图像坐标系转换为世界坐标系。
点云和深度图都会出现深度信息的缺失,因为往往传感器只能捕捉物体表⾯的信息。
.obj .off .ply格式都是3D mesh格式,即物体被划分成若⼲个微⼩单元(三⾓形,或其他形状)。点云格式有*.las ;*.pcd; *.txt等。
voxel体素与2D中的pixel对应,是3D空间⾥⼀种标准的可处理的单位格式 点云数据有三⼤问题:⽆序性、稀疏性、信息有限(和稀疏性也相关,只能提供⽚⾯的⼏何信息)。
3D数据集汇总
ModelNet40
SUN-RGBD
ScanNet
3D⽬标检测有很多种玩法,有纯基于RGB图像的,这种往往需要多个视⾓的图像作为输⼊;有纯基于3D点云的,如接下来要介绍的PointNet,PointNet++和VoteNet都是基于纯点云数据的;也有使⽤2D⽬标检测驱动3D检测的,如frustum-PointNet,就是先完成2D ⽬标检测确定object位置,再3D box。
输⼊: B*N*3. B是batch size, n是点的个数, 3是每个点的特征数, 有些传感器或数据集可能还有点属性(旋转, 反射强度等)。训练的数据集是ModelNet40(包含40种室内家具的点云,由其CAD模型的surface数据得来)
T-net: ⽤于⽣成transformation矩阵(3*3尺⼨⽤于对初始点云的处理,64*64⽤于对中间feature做处理), 接着和原始点云数据矩阵相乘做转换. T-net中有3层卷积+1层max_pool+2层FC+1层输出层, 输⼊shape B*N*3, 输出shape B*3*K (注:第⼀个transform⾥K=3, 第⼆个transform⾥K=64) .
input transform: 输⼊shape B*N*3, T-net shape B*3*K, 相乘之后输出shape B*N*K, 即B*N*3,与原始点云数据shape相同. input transform的作⽤相当于提取了原始点云数据或特征层⾥的特征, 对坐标空间进⾏了变换.(个⼈认为这么做是因为点云数据本⾝没有很强的顺序关系,对于卷积来说,相当于设定了点云数据的顺序关系,transform之后对位置空间进⾏了⼀个调整,有点类似于hough vote的图像空间转成坐标空间).
mlp: 两层卷积, filter都=64, 第⼀层kernel=[1,3], 第⼆层kernel=[1,1], 输出shape B*N*64
feature transform:与input transform类似,除了K=64
分类任务最后输出的output score shape为40(40类分类任务), 分割任务将global feature复制n份, 如图
接在之前的特征层后, 最后输出shape为B*N*50 (我没有弄懂这⾥为啥是50不是40, 不应该是40类么?是不是因为分割任务可能会分割成其他物体?)
在PointNet中, 直接对输⼊的点云数据整体进⾏卷积和max_pooling,忽略了局部特征. 且特征提取忽略了密度不均匀的问题, PointNet++解决了这2个问题.
Hierarchical Point Set Feature Learning
三步: 采样中⼼点, 邻点建局部区域, 提取局部区域特征
1. sampling layer: 该层的输⼊是原始点集N*(d+C), d为xyz坐标数据,C是点特征数据. 使⽤FPS算法从数据集中选出中⼼点集
FPS算法: 随机选取⼀个点加⼊中⼼点集合, 之后选择离中⼼点集合⾥的点最远的点加⼊中⼼点集合中, 迭代选取中⼼点(后⾯选取的点需要和之前中⼼点集合中所有的点做距离计算metric distance),直到中⼼点集中点的个数达到阈值.
2. grouping layer: 该层的输⼊是原始点集N*(d+C)和sampling出的中⼼点集N'*d(N'是中⼼点个数,中⼼点只需要d坐标信息,不需要特征信息). 该层的输出是点集(point sets)的groups, 每个点集的shape是N'*K*(d+C), 每个group对应⼀个局部区域, 共有N'个局部区域, K是中⼼点周围的点的个数. 不同的group的K的值不⼀样. 虽然每个group含有的点的数量可能不同,但是使⽤pointnet结构提取出来的特征是维度⼀致的(每层特征图使⽤了全局max pooling)
Ball query: 使⽤KNN选取中⼼点周围的点集也没有考虑到密度不均匀的问题. ⽂章使⽤了⼀种Ball query的⽅法,就是在中⼼点周围取⼀定半径⾥的所有点.
3. PointNet layer: 使⽤pointnet的⽹络提取局部区域的特征, 输⼊是grouping出的groups, 每个group的shape是N'*K*(d+C), 输出是N'* (d+C'), 邻点的坐标减去中⼼点的坐标,作为他们的新坐标. 点特征shape C被embedding成shape C', K个邻点被抽象成⼀个特征.
Robust Feature Learning under Non-Uniform Sampling Density
针对密度不均匀的问题,提出密度适应的特征学习⽅法: PointNet++ layer 替代PointNet layer一次性浴缸套
点云数据有密度不均匀的问题, 近多远少, 对于密度不均匀的数据使⽤相同尺⼨的特征提取是不合适的(如卷积的感受野对远处的点集应该更⼤),⽂章使⽤了两种特征提取⽅法:
1. MSG(multi-scale grouping多尺度组合) 对每个group都⽤不同尺度⼤⼩的⽹络来提取特征,再叠加在⼀起怎么扣出水指法图
2. MRG (multi-resolution grouping多分辨率组合)每层对某个局部区域的特征提取由两部分组成: 基于上⼀层输出的特征提取到的特征
+该区域对应的原始点集提取出的特征. 前者经过了两层特征提取,感受野更⼤, 适⽤于⽐较稀疏的点集. ⽽后者只做了⼀次适⽤于⽐较稠密的点集.
电动开瓶器:以⼆维图像驱动三维点云中的物体检测
山地单轨运输车
PointNet和PointNet++基于3D点云数据做分类和分割,f-pointnets基于RGB图像+深度信息使⽤pointnet和pointnet++的结构做了⽬标检测。f-pointnets考虑了室内和室外的场景,基于KITTI数据集和SUN RGB-D 3D detection benchmarks数据集进⾏了训练。
使⽤到2D RGB图像的原因是当时基于纯3D点云数据的3D⽬标检测对⼩⽬标检测效果不佳,所以f-pointnets先基于2D RGB做2D的⽬标检测来定位⽬标,再基于2d⽬标检测结果⽤其对应的点云数据视锥进⾏bbox回归的⽅法来实现3D⽬标检测。使⽤纯3D的点云数据,计算量也会特别⼤,效率也是这个⽅法的优点之⼀。
下图是该算法的架构图:
1. 使⽤成熟的2D CNN⽬标检测器(Mask RCNN)⽣成2D检测框,并输出one-hot 分类向量(即基于2D RGB图像的分类)。
2. frustum proposal generation视锥框⽣成: 2D检测框结合深度信息,到最近和最远的包含检测框的平⾯来定义3D视锥区域
frustum proposal。然后在该frustum proposal⾥收集所有的3D点来组成视锥点云(frustum point cloud)。由于视锥的⽅向会对其包含的点云数据影响很⼤,所以需要标准化视锥的⽅向,论⽂的做法是对视锥的坐标系进⾏旋转,直到视锥的中轴线和image plane垂直。这个视锥的标准化可以提升算法对旋转变化的性能。视锥坐标系变换的代码见,过程见下图。provider是⼀个数据⽣成器,除了坐标系的变换,也包括3D视锥点云的⽣成。
1. 变换视锥的坐标系实际上就是变换点云的坐标系,从点云的⾓度来看,坐标系是z is facing forward, x is left ward, y is
downward,frustum rotation实际上就是对点云数据绕y轴旋转,变换矩阵为[[cosval, -sinval],[sinval, cosval]],将其乘在y 轴坐标上即可。其中正余弦的值由⾓度算来,旋转⾓度在中定义,先到2d box的中⼼点(x,y),给其任意添加⼀个深度
z(由于是计算⾓度,不需要z的精确值,取个⼤于0的数即可),然后将(x,y,z)使⽤⾥的project_image_to_rect转换成3D中⼼点(x',y',z')(该函数只转换了x,y,具体细节见代码)。之后frustum_angle = -1 *
np.arctan2(box2d_center_rect[0,2],box2d_center_rect[0,0]),其中x'=box2d_center_rect[0,0],
z'=box2d_center_rect[0,2]。(⾥描述了关于2d image数据和3D激光点云数据之间转换的calibration。
2. ⽣成3D box(通过3d box的长宽⾼求出8个corner在3D space下的坐标),并获取包含在3D box⾥的3D点云(先要使⽤
calibration⾥的转换函数将3D激光点云数据转换成3D rect数据)。
3. 获得相应的3D点云后,,接下来是3D Instance Segmentation PointNet, 该部分实际上就是使⽤pointnet++的
防静电推车segmentation的⽹络架构进⾏分割,与pointnet++的区别是这⾥提前完成了检测,这⾥的segmentation是⼀个⼆分类。见下图左。之前2D⽣成出的one-hot class vector在feature propagation layers时与set abstraction layer的输出concat在⼀起,个⼈理解是这样可以给后⾯的分割添加⼀个先验,让分割更准确。需要注意的是,这⾥的分割除了获取3D segmentation 之外,也是为下⼀步⽣成3D box过滤3D点云,因为之前的点云的范围⽐较⼤,会影响3D box的精度。
官⽅使⽤了两种⽹络来训练,v1是基于pointnet架构训练的模型,v2是基于pointnet++训练的模型。
(2019)
f-pointnet 使⽤2D转3D的⽅法object的中⼼,进⾏了⼀系列的坐标系转换。直接基于3D点云中⼼⽐较困难,因为3D点云往往是object表⾯的点,且具有稀疏性,3D object的中⼼可能离这些点很远。本⽂使⽤了含有类似于传统Hough Voting机制的⽹络,来通过投票⽣成新的邻近中⼼点的点,再基于这些点分组和聚合,最后⽣成3D box。 ⼴义霍夫变换和霍夫投票
参考:
霍夫变换⼀般适⽤于有解析表达式的⼏何形状⽬标检测,例如直线、圆、椭圆等。变换的过程是将解析表达式表达的图像空间转换成参数空间,对于直线来说,直线上的每个点变换到参数空间中都是⼀条直线,这些直线共同的交点在参数空间中的坐标就是图像空间中的参数。寻这个交点的⽅法就是霍夫投票,即统计参数空间中每个点被运⽤的次数(以空间中每个点的坐标为key,使⽤的次数为value),峰值点即为参数点,霍夫空间中的峰值点可能不严格的在同⼀个坐标上,需要允许⼀部分误差。
参考:,
⼴义霍夫变换可⽤于没有解析表达式、不规则形状的⽬标检测。没有解析表达式,⽆法直接将图像空间转换到参数空间进⾏投票;即使到对应解析式,参数也必定很多,参数越多参数空间的复杂度指数增长。以下是⼴义霍夫变换的做法:
1. ⾸先要适⽤于⼀个边缘模板,检测出图像的边缘点。这是因为边缘是检测和区分图形最重要的特征。
2. 建⽴给定图形的R-table:
1. 准备⼀个有k种⾓度 ( ) which increases from 0 to 180 degrees with increment 的表,k是梯度
⽅向(即边缘某点切线的法向量)的分辨率。
2. 在2D图形⾥到⼀个参考点(如:重⼼),对边缘上的每个点计算两个参数
3.
3. 投票:对于给定边缘点信息,我们通过查表然后计算出参考点位置,然后根据投票机制,确定投票最多的位置。
Deep Hough Voting
霍夫投票很适合点云数据,⼀是因为投票针对稀疏集合设计,⼆是因为其积累少量的局部信息以形成可靠的检测。为了将霍夫投票⽤于3D 点云数据,本⽂做了以下调整:
兴趣点 (Interest points) 由深度神经⽹络来描述和选择,⽽不是依赖⼿⼯制作的特性。
投票 (Vote) ⽣成是通过⽹络学习的,⽽不是使⽤codebook(相当于R-table)。利⽤更⼤的感受野,可以使投票减少模糊,从⽽更有效。此外,还可以使⽤特征向量对投票位置进⾏增强,从⽽实现更好的聚合。
投票聚合 (Vote aggregation) 是通过可训练参数的点云处理层实现的。利⽤投票功能,⽹络可以过滤掉低质量的选票,并⽣成改进的