【6D位姿估计算法】linemod的介绍与代码测试
一、LineMod算法介绍
LineMod算法是Hinterstoisser等人在2011年提出的,通过采用模板匹配的方法,解决了杂乱场景下少纹理三维物体的实时监测与6D位姿估计定位问题。
算法使用3D物体的RGB-D数据作为输入,通过PCL数据处理库分析目标点云数据,利用预先采集好的三维物体的无噪声或少噪声模板经过较短时间训练得到物体各个方向每个像素点梯度方向和幅值变化,在较短的时间内完成模板训练。识别时用采集到的点云数据与模板对比得到物体信息、位姿和置信度。
需要注意的是由于LineMod算法是将整个物体作为一个单个模板用于之后的模板匹配,因此限制了其不具备多目标及遮挡场景的识别能力。
二、LineMod算法原理
总的来说,LineMod算法的实现可分为以下三个阶段。
- 模板采集阶段:在多个视角、多种距离、多个方向上对目标物体的特征进行采集
- 模板训练阶段:计算目标物体的特征点和特征向量的计算,得到各特征点的坐标并进行存储
- 模板匹配阶段:对被测图像进行特征处理,延梯度方向展开得到预处理相应图,然后构造响应表进行线性化存储,最后通过滑窗匹配计算与模板的相似度。
2.1 模板采集阶段
LineMod是基于模板匹配的算法,因此在进行三维物体识别前需要获取识别物体的低噪声、高精度的完成模型,获取模型有两种方法。
- 通过深度相机从多个视角、多个距离、多个方向对目标进行模板采集,但这种方法容易产生较多的噪声,对之后的目标识别会产生干扰,且费时费力。
- 通过OpenGL手动渲染想要识别的三维物体的模型,利用Solidworks等三维仿真软件就可以对物体进行三维模型的创建和渲染,这种方法可以很好的控制噪声,有利于后续算法对物体的识别精度。
目前网上已经出现了很多常见三维物体的模板库,例如:Thingiverse、YouMagine、Pinshape,等网站都提供常见物品的三维物体模型文件。
2.2 模板训练
LineMod算法将模板图像上各视点的梯度和法向量方向的特征进行提取保存编码,这些根据特征生成的二进制字符串就是之后进行模板匹配的关键。在模板训练阶段需要进行特征点的特征向量的计算、特征点坐标的计算、以及信息的存储。
1. 计算特征点的特征向量
- 将模型的RGB-D和物体的ID信息导入算法。
- LineMod算法会在空间中进行不同角度、不同缩放尺度,进而得到待训练模板。
- 待训练模板、训练距离、掩模图像作为特征点的输入,通过高斯模糊和低通滤波完成候选点的去噪以及预处理。
- 通过Sobel算子计算候选点梯度幅度,得到物体图像边缘。
- 通过Phase函数计算候选点的梯度方向。
- 在360°空间范围内对候选点的梯度方向按照16个区间共十个方向进行投影,量化候选点的梯度方向
- 通过设置阈值和3x3梯度直方图统计3x3区域内的候选点梯度方向,将候选点最多的梯度方向作为整个区域的梯度方向
- 得到特征点的梯度方向和梯度幅值,保存特征计算结果。
2. 特征点坐标计算
LineMod算法通过遍历输入图像的图像金字塔,通过下采样的方式提取金字塔每一层特征点所在的坐标位置,在训练中不断循环计算特征点坐标并进行修正,最后得到3x3区域内特征点对应的坐标位置。
3. 特征点信息存储
训练得到的特征向量(梯度幅度和梯度方向)和特征点的坐标位置后,结果通过shapes.save_infos
保存训练信息,通过detector.writerClasses
写入预设待匹配模板特征点信息。
2.3 模板匹配
输入的测试图会将图像的宽度和高度调整为16的倍数便于后续的图像处理,各个特征点的特征向量和坐标计算与模板训练阶段一样,在得到测试图像特征点的特征向量和坐标后,进行以下操作。
1. 梯度方向展开
将每一个像素点及其3x3的邻域按照离散化的方向进行或运算,并按邻域直径T循环TxT次完成邻域像素点的梯度方向值遍历,并在内存中存储为连续的特征信息数据。
梯度方向展开的过程如图:a)像素点的梯度方向;b)以该像素点为中心进行3x3邻域梯度方向展开;c)每个邻域对应方向量化值。计算结束后将会创建梯度响应表(图c)用于存储梯度方向量化值。
2. 线性化存储
LineMod算法会预处理相应图,将像素点x处的多个特征进行编码,由扩散得到的多个特征将编码的独一无二的字符串会在匹配阶段使用。LineMod算法通过预先为每个离散方向创建n0个查超标供与二进制字符串匹配搜索过程,而查找表的索引号对应该字符串、索引值对应像素点的位置与离散特征方向的余弦值。这样就完成了测试图像像素特征处理、方向扩散、构造响应表以及线性化存储梯度方向量化值的过程。
3. 相似度计算
LineMod提取出训练阶段的模板特征点信息,通过将模板在测试图像上进行水平和垂直方向上的滑窗匹配,比较训练模板特征点与测试图像对应像素点在查找表上对应的梯度值差异性,产生一个二维相似度矩阵,完成测试图像的一次滑窗匹配。
测试图像在不同的金字塔不断进行模板的滑窗匹配,得到不同的相似度(梯度方向余弦值)。对同一个模板进行相似度叠加得到整体相似度,这样就是一个测试图像对应不同位置方向角度模板得到不同的整体相似度,通过相似度即可判断是否匹配成功。
三、LineMod算法实现
3.1 运行环境搭建
系统环境:ROS系统(本文使用Ubuntu20.04+ROS Noetic)
[[01_Ubuntu20.04安装ROS Noetic|ROS安装方法参考此文章]]
硬件设备:3D相机(本文使用Realsense D435i)
Realsense的安装参考Github主页
如果出现[camera/realsense2_camera_manager-2] process has died exit code 127的问题
则将LD_LIBRARY_PATH=/opt/ros/indigo/lib加入到.bashrc中
这里使用realsense官网的例程
1 | roslaunch realsense2_camera rs_rgbd.launch |
发布的RGBD信息为:
信息 | 话题 |
---|---|
rgb_frame_info | /camera/color/camera_info |
rgb_image_topic | /camera/color/ |
depth_frame_info | /camera/depth/camera_info |
depth_image_topic | /camera/depth/image_rect_raw |
3.2 安装ork
在已经完整安装ROS的情况下,运行下面指令即可安装
1 | export DISTRO=noetic |
进入catkin_ws/src
文件夹下,运行下面的指令即可
1 | git clone https://github.com/wg-perception/object_recognition_msgs |
1 | cd .. |
3.3 下载ork_tutorials
进入catkin_ws/src
文件夹,下载ork_tutorials
包。
1 | git clone https://github.com/wg-perception/ork_tutorials |
进入刚下载的包中ork_tutorials/data
文件夹,执行以下语句
1 | rosrun object_recognition_core object_add.py -n "coke " -d "A universal can of coke" --commit |
1 | cd catkin_ws/src |
1 | cd catkin_ws/src |
参考文章
LineMod模板匹配算法的原理与实现 (第一篇 原理及公式)
# LineMod模板匹配算法的原理与实现 (第三篇 原理及实现)