前言
在之前的文章中,我们基于模版匹配的方法估计了单个目标的位姿,但是这种方法只适用于场景中只有一个目标,一旦场景中有多个目标,算法很容易失效。一方面,一个完整的抓取场景往往范围比较大(相对于单个零件而言),采集到的常见点云数量会很多,尤其如果使用的一些高精度的工业级点云传感器,可以生成数百万的点。如果是只选取这大量点中的少量的关键点计算特征向量,可能会导致无法匹配,选的太多速度又太慢。另一方面,采集整个场景肯定会采集到背景,对背景进行点云特征向量计算也会对算力的浪费。
针对上述的问题,采用两阶段的算法往往更加合理。第一阶段,提取含有单个目标点云数据的局部点云区域,第二个阶段,在局部点云区域中估计目标位姿,这时问题就已经转化为单目标位姿估计了。
这篇文章主要讲一下第一阶段怎么做,并提供一种较为简单的操作方式。
一、算法思路
沿着先提取局部ROI这个思路,可以很自然地想到目标检测(找一个bounding box)或者语义分割(像素级分割)这两种方式。
如果是在点云数据上进行,有个问题:标注比较困难,现在开源的点云标注软件好像不是很多,我尝试了point-cloud-annotation-tool、annotate以及semantic-segmentation-editor感觉多少都有点麻烦,尤其是想到还要采集很多点云数据,然后一个个标注,相当麻烦。
所以我选择了另一种方式,那就是在RGB图像上先进行二维的ROI提取,然后将这个ROI映射到三维点云空间中去(具体如何映射后面讲),得到局部点云数据后问题就又变成了单目标位姿估计的问题了。
在RGB图像上同样可以采用语义分割或者检测的方式。虽然理论上来说,分割的方式会更好,但是因为懒,所以还是用检测的方式吧,毕竟数据集要标注的图片不是少数。
有了思路就开始动手实现了,目标检测网络千千万,随便找个开源的,(又或者自己写?我做的这种场景其实挺简单的,没必要自己整一个)。正好收藏夹里还有三年前收藏的YoloV3的github,就它了吧。
二、用yolov3训练自己的数据集
2.1 制作数据集
首先就是去拍一些场景的图像,改变一下光线,角度,远近这些参数。
然后下载一个LableImg,这个很容易使用,下载下来就是一个exe可以直接使用。开始标注,操作截面如下。lableimg下载地址
根据自己的场景决定一下要采集多少图像,我这里总共是采集了大概六百张图像(标注到头昏眼花)
部分样本如下:
2.2 开始训练
数据集有了,就要开始训练了,其实如果你一点都不懂深度学习也无所谓,yolov3代码基本是傻瓜操作了。
首先下好代码yolov3 github地址
然后如何在自己的数据集上训练的官方的教程Train Custom Data也有了。开始训练就完事儿了,记得划分一下训练集,测试集和验证集,可以按照8:1:1的比例划分,另外,这种很简单的场景用tiny版本就行了。
2.3 结果分析
把实验结果记录一下,然后在验证集上看看效果。
三、二维ROI向三维点云的映射
得到了局部的ROI,下一步就是将他向三维点云空间中映射了。这是原理图。
一般相机就是RGB相机获取二维图,红外相机获取深度,其实就是标定一下这两者之间的关系,得到一个变换矩阵。但是这些也不用我们自己做了,一般集成好的点云相机都是能直接读出这个变换矩阵的。realsense,Kinect都是可以的。在网上也很容易搜到教程。
映射完了之后,咱们就能得到很多局部点云数据了。以下是YOLO检测结果和映射完后的结果。
四、从局部点云数据中估计目标位姿
用之前单目标位姿估计的方式估计零件的位姿,图中显示了(a)(b)©(d)(f)的结果,看起来效果还是可以的。但是有一个(e)估计失败了,应该是遮挡太多了的缘故,再调调参数说不定也可以检测出来。