APP下载

PCL环境搭建与在三维重建中的应用

2018-11-19姜子鹏卜凡亮

软件导刊 2018年11期
关键词:特征描述源代码三维重建

姜子鹏,卜凡亮,秦 静

(中国人民公安大学 信息技术与网络安全学院,北京 100038)

0 引言

在虚拟环境中,三维重建是处理、分析和操作模型的基础[1]。根据获取场景的不同可将其分为基于纹理信息和基于深度信息的三维重建[2]。基于深度信息的重建可分为接触式和非接触式,非接触式技术又有主动和被动扫描的区别。常见飞行时间(time of flight,ToF) 相机、激光系统、结构光系统和 Kinect 深度传感器等[3]均使用了非接触式主动扫描技术。

现有三维重建技术可分为实时和非实时技术。非实时技术主要有双目视差法、明暗恢复形状法等。因存在计算复杂、操作繁琐等问题,以上方法并不能实时应用于三维场景重建。实时三维重建技术依靠设备发出光线与物体发生反射后,通过设备接收深度信息以完成重建。目前实时三维重建技术主要有: 单激光线扫描法[4]、傅里叶变换轮廓法、彩色条纹结构光法等。实时三维重建算法效率高,处理数据量小,能有效处理噪声。目前能用于实时三维重建的设备有基于结构光的 Kinect[5]、基于Time of Flight的Camcube[6]和 Mesa Imaging Swiss Ranger 4000[7]。

针对三维重建的技术方法,国内外学者进行了大量研究。刘利刚等[8]采用一种实用性方法对不同视角下的不同身体部位进行配准,利用多个外设协调工作实现对动态和静态人体三维重建。刘鑫等[9]给出一种物体快速重建方法,借助图形显卡GPU,提出一种简单易用的粗标定方法和全自动快速物体重建方法。针对Kinect Fusion 需要大量 GPU存储空间的问题,曾鸣[10]提出一种基于八叉树的数据结构,并在数据节点存储符号距离函数,在八叉树结构的基础上,重建更新和表面预测,从而高效利用 GPU 的并行计算能力。Rushmeier等[11]将基于深度图像的三维重建过程分为几何处理和面的表示。Peter Henry等[12]利用SIFT特征匹配定位和TORO优化算法,设计了一种实时视觉SLAM系统。Fiorairo等[13]提出了RGB-D SLAM算法,使用 Hogman优化算法和SURF特征匹配搭建实时性高、鲁棒性强的重建系统。Harris 等[14]首次提出角点的定义。Shi等[15]在此基础上进行改进,提出一种效果更好的角度提取方法。目前使用比较广泛的特征点提取和匹配方法是SIFT(scale-invariant feature transform)方法[16]。

本文结合现有研究课题,聚焦于PCL环境搭建过程及点云库在三维重建中的应用,以SIFT算法为基础,结合FLANN算法,对图像进行特征提取与匹配,以提高特征匹配效率。

1 PCL

点云库,全称Point Cloud Library (PCL)[17],是一个既可以单独使用又可以作为辅助工具的工程,本质是一个开源C++编程库,可以在Windows和Linux等操作系统上运行。点云库常被用于处理点云数据和二维或三维图像。建立点云库的最初目的是为三维点云数据处理和ROS[18]研究及应用建立一个基础架构。PCL第一个基础算法是由Dr. Rusu开发,于2009年由Willow Garage公司进一步开发完成。若OpenCV[19]是二维信息获取与处理的结晶,则点云库在三维信息获取与处理上具有同等地位。

1.1 PCL结构

PCL将三维重建和点云数据处理中所有常见功能整合在一起,保证了算法紧凑性和结构清晰性,提高了算法代码简洁性[20]。PCL功能如图1所示。

图1 PCL功能模块

1.2 PCL模块功能

PCL模块功能[21]包括:① Common模块包含常用库,提供常用函数;②Filters模块,去除噪音点,为特征提取等过程提供过滤器;③Features模块,实现边界点估计, 计算NARF描述子等;④ Keypoints模块,实现关键点提取,决定在何处提取特征描述符;⑤Registration模块,实现点云的配准方法;⑥Kd-tree模块,实现基于FLANN的KD树最近邻搜索;⑦Oc-tree模块,实现基于八叉树最近邻搜索;⑧Segmentation模块,实现点云分割提取;⑨ Sample Consensus模块,对点云进行拟合;⑩Surface模块,实现表面重建技术;Range Image模块,深度图,由Kinect获取后可转换为点云;IO模块,实现PCD (Point Cloud Data) 文件的读写和数据输入输出;Visualization模块, 实现基于VTK依赖库的三维可视化。

2 Windows运行平台

本文编译环境为Microsoft Visual Studio 2010,操作系统分别是32位Windows 7和64位 Windows 10,不适用于其它编译环境。

2.1 预编译包搭建

2.1.1 预编译包介绍

预编译包是一个集成了PCL中第三方依赖库的安装包,因依赖库被提前编译过,安装后即可直接使用。

为方便初学者在最短时间内体验到PCL的强大功能,PCL官方网站为Windows用户提供了经典PCL 1.6.0版本及其相应PDB(程序数据库)文件下载。适合该版本PCL的运行系统是编程兼容性最强的Windows7(32位)操作系统。PCL预编译包如图2所示。

图2 PCL预编译包

2.1.2 预编译包安装

安装预编译包时,需要注意运行版本的选择,否则安装时系统可能因不兼容而报错。因为预编译包中的OpenNI版本老旧,所以为保证能在PCL配置完成后,顺利通过外接设备(Kinect)获得包含点距离信息的深度图像,需要另外安装最新的OpenNI(开放式自然交互)相关组件。本文选择安装的32位PCL1.6.0版本安装包以及OpenNI相关组件如下所示:

PCL-1.6.0-AllInOne-msvc2010-win32.exe

OpenNI-Win32-1.5.4-Dev.msi

Sensor-Win-OpenSource32-5.1.0.msi

安装预编译包时选好安装路径,推荐选择默认的3个安装包安装目录,以便系统自动设置环境变量及安装路径,然后按照指示完成安装。预编译包及相关组件安装完成后,手动下载图2显示的PDB(程序数据库)文件,再解压到预编译包安装目录的“bin”文件夹下。

完成以上操作后,需要对OpenNI进行运行测试。运行安装目录中的测试程序Ni- Viewer(64).exe,看到图3所示的影像后,说明OpenNI安装成功,能够被PCL调用,可进行下一步工作。

图3 OpenNI运行示例

2.1.3 环境变量设置

一般情况下,预编译包安装完成后,系统变量会被自动设置,如果没有,可以手动添加。在系统变量里添加“PCL_ROOT:(你的PCL的安装路径)”,在系统变量Path里加入:%PCL_ROOT%in。

2.1.4 包含目录设置

本文PCL安装在C盘。首先,在VS新建一个项目,在属性管理器中找到VC++的包含目录,添加第三方依赖库头文件夹路径。第三方依赖库“include”头文件夹可在PCL安装目录中“3rdParty”文件夹中找到,见图4。

图4 头文件路径添加

2.1.5 库目录设置

在新建项目的属性管理器中找到VC++选项,在其库目录中添加 C:Program Files PCL 1.6.0lib等第三方依赖库静态链接库的路径。第三方依赖库“lib”库文件夹也可在PCL安装目录的“3rdParty”文件夹中找到,见图5。

图5 库文件路径添加

2.1.6 附加依赖项设置

添加附加依赖项,将本文安装的几个第三方依赖库静态链接库名称全部添加到“工程属性页→链接器→输入项”中,见图6。第三方依赖库静态库可以在相应安装目录下的“lib”文件夹中找到。

图6 静态库添加

由于需要添加静态链接库的数量过多,所以无法一一列举,只能以截图的方式显示部分添加的静态链接库,见图7。需要添加的静态链接库数量为199个,图7展示的只是其中的22个,其余静态库未被展示。

图7 部分静态链接库

2.2 利用第三方编译包的源码搭建

本文推荐利用第三方库编译包从源码搭建PCL,虽然没有利用PCL预编译包直接安装的便捷,但比手动编译第三方依赖库和源代码简单、省时。这种配置方法一方面继承了源码搭建的优点——既可了解源代码编译工作原理和过程,另一方面又克服了预编译包只能安装特定PCL版本的缺点,能够在允许范围内随意切换PCL源代码版本进行编译,随时补充和更新PCL功能。

2.2.1 第三方依赖库安装

搭建过程必备的第三方依赖库有:用于共享指针和线程的Boost(C++半标准库)[22];用作SSE优化数学的矩阵后端Eigen(矩阵类库)[23];基于KD树中的快速近似最近邻搜索的FLANN(近似最近邻搜索库);用于三维点云渲染和可视化的VTK(可视化工具包)[24]。

另外,可以选择性安装的依赖库有:用于曲面上凸凹壳分解的QHull(计算几何库);OpenNI (RGB-D传感器库);具有图形用户界面的应用程序Qt。

第三方依赖库有多个版本,需要选择跟操作系统、编译环境和PCL相匹配的版本,才能保证PCL顺利配置。本文系统环境参数包括:①操作系统,64位Windows 10;②编译环境包括Microsoft Visual Studio 2010(提供Kinfu模块);③第三方依赖库,如图8所示。

图8 第三方依赖库

2.2.2 源代码编译

首先获取PCL源代码。源代码版本众多,到目前为止已经更新到PCL 1.8.1,源代码可从GitHub官方网站下载。图9为本文下载到的多个PCL版本。

图9 源代码的几个不同版本

运行CMake - GUI(见图10)应用程序,点击“Configure(配置)”按钮。

图10 CMake - GUI用户界面

本文使用Microsoft Visual C++ 2010编译器,构建32位PCL,可选择“Visual Studio 10”生成器;构建64位PCL,可选择“Visual Studio 10 Win64”。本文选用64位PCL。

选择生成器后,点击Finish关闭对话框窗口。CMake将开始配置PCL并查找其依赖库。CMake在寻找依赖库时会出现多种找不到路径的情况,需人工帮助寻找。

对PCL源代码进行Configure和 Generate,然后打开CMake生成的VS2010解决方案进行编译即可,对ALL-BUILD和INSTALL各Debug和Release编译一次。Debug生成的是调试版本的程序,使用者可随时对程序代码进行调试修改;Release生成的是完美编译后封装好的程序,无法进行调试。建议后续使用过程中使用Release版,在使用过程中不会影响程序代码。对所有项目进行编译需约半小时的时间消耗。

2.2.3 环境变量设置

在操作系统环境变量里添加系统变量。添加过程与预编译包系统变量添加过程相同。

2.2.4 工程目录及依赖项添加

在VS2010新建项目中的属性管理器里添加包含目录、库目录和依赖项,添加过程同预编译包工程目录和依赖项的添加过程。

3 Linux运行平台

3.1 依赖库安装

本文选择Linux运行平台版本为Ubuntu16.04。

首先,打开Ubuntu终端,下载第三方依赖库,命令行代码见图11。

图11 安装第三方库命令行代码

在Ubuntu终端逐行输入图11中的命令并运行,在保证每一个依赖库安装成功后,才可进行后续操作。

3.2 源代码下载

从Linux社区下载源代码,其命令行代码见图12。

图12 源代码下载命令

源代码文件218.43M,包含106 789个子文件。下载过程耗时较长,见图13。

图13 源代码下载

3.3 编译源代码

完成安装依赖库和下载源代码两个准备工作后,可开展编译源代码。按照图14中的5句命令逐一输入终端并运行,即可进行源代码编译。

图14 编译源代码

经过安装依赖库、下载源代码和编译源码步骤后,Linux平台PCL安装成功,如图15、图16所示。

图15 安装好的PCL模块

图16 PCL配置成功

4 应用实验

4.1 特征点匹配

4.1.1 FLANN 特征紧邻像素匹配

近邻搜索问题在图像识别和数据分析等各种应用中具有重要意义。但是,没有一种算法比标准的蛮力搜索能更好地在高维度空间中解决该问题。Muja & Lowe[25]于2009年提出了基于K均值树[26]或KD树[27]搜索的FLANN算法,该算法可以根据数据集或点云分布特点推荐建立索引类型。FLANN (近似最近邻快速库)是用C++编程语言编写、用于执行快速近似最近邻搜索的库。同时,FLANN算法在高维空间最近邻查找中不会受到局部敏感哈希[28]影响。该算法运用的特征空间是向量空间Rn(n维),其重点在于使用欧几里得距离[29]找到目标点邻近点。特征点g和特征点k的特征分向量可以分别记为Dg和Dk,欧氏距离d(g,k) 可以表示为:

d(g,k) =

(1)

本文首先利用 KD树将二维图像数据点划分为几个特定部分,目的是在KD树结构中寻找与目标点距离最近的欧氏距离。将所有检索到的欧氏距离d(g,k)通过KD树存储,然后可有效搜索到与目标点距离最近的点。整个搜索过程是一个自上而下的递归过程,将查询点和分割点的值进行循环比较,判别查询点在左区域还是右区域,再进行循环和对应分割点比较,直到搜索成功为止。

4.1.2 SIFT匹配算法

Lowe[[30]于2004年提出了一种具有划时代意义的高效局部特征算法—SIFT(Scale Invariant Feature Transform)算法。在不同尺度空间中寻找特征点进行描述,最后进入算法核心的匹配环节。因此可以将SIFT算法概括成以下步骤(见图17):

图17 SIFT算法流程

(1)搜索特征点。根据尺度空间理论[[31],在图像多尺度空间中寻找并确认每一个尺度空间里对应极值点,获得极值点所在位置的像素坐标,这些坐标包含备选特征点位置信息。剔除低对比度的极值点和易受噪声干扰的备选特征点,得到被筛选过的特征点集。

(2)详细描述提取的特征点。对特征点的邻域进行梯度加权计算,得到对应的邻域梯度幅度值和方向,利用直方图方法获取每个邻域梯度主幅度值和主方向;然后再通过计算得到以该特征点为中心像素点的梯度主幅度值和主方向,利用特征描述向量描述该特征点。

(3)关键点匹配。对于两个匹配特征点存在最邻近匹配对与次邻近匹配对,将最邻近欧式距离与次邻近欧式距离进行相比,若比值小于某一设定阈值则为正确匹配。最后采用RANSAC算法[ [32]对点对进行进一步优化。

4.1.3 实验过程

利用Kinect获取两张RGB图像(见图18、图19),作为初始输入图像。

图18 RGB1

图19 RGB2

图19是彩色摄像机在图18的视角基础上向右平移后拍摄的图像。

首先,使用SIFT算法,利用关键点周围的像素,计算关键点描述子以便对关键点进行描述,计算参数为关键点半径及角度。特征描述子不是单纯的标量,还是一个矩阵,一个特征向量为一行。当两个特征点越相似,其描述子也越相似。图20是对初始RGB1图像进行特征描述子计算后的输出图像。

图20 RGB1特征描述子选取

图21 特征描述子粗匹配

然后,使用FLANN搜索匹配算法对已经计算出来的特征描述子进行匹配(见图21)。经过对关键点特征描述子粗匹配后,总共得到620对匹配点对。从结果可以看出,仅依靠描述子匹配得到的结果繁多,且把许多并不相似的点对也进行了匹配。

针对不相似点对过多的问题,本文首先进行一次筛选,去除第一类误匹配情况,即去掉相距距离太大的点对。筛选原则是去掉大于4倍最小距离的点对。经过一次剔除处理,错误的匹配对明显减少(见图22),与图21特征描述子粗匹配相比,输出的图像干净整洁了许多,处理后的关键点特征匹配点对骤降为128对。第一次筛选处理剔除了492对无关匹配,降低了后续处理的工作量,节约了时间。

图22 一次处理后匹配点对

图23 二次处理得到的特征点对

通过细致观察可以发现,两个RGB源图像之间只发生了水平方向旋转,所以正确的匹配线应该是水平的,非水平匹配线为误匹配。图22显示出匹配点对存在个别错误的匹配。针对出现的第二类误匹配情况,可以利用PCL的RANSAC算法进行二次筛选处理(见图23)。

经过二次处理,得到图23的结果。剔除了第二类误匹配情况后,得到了一幅含有16对特征匹配点对的图像,二次处理去掉了112对误匹配点对。通过观察表1以及图23可以发现,利用PCL的RANSAC算法可以得到一个数量适中且较为准确的关键点特征匹配结果,并且极大降低了误匹配率。

表1 匹配点对处理结果对比

但在图23中,特征点对仍有2对误匹配,这是由于两幅RGB源图中的关键点特征描述子过于相似导致的。针对图23中出现的第三类误匹配情况,还需要后续通过调整关键点搜索匹配算法、细化筛选处理标准以及相关参数解决该问题,以得到更好的匹配结果。

4.2 点云处理

4.2.1 点云实时抓取

通过调用PCL中输入输出模块(IO)的抓取函数和可视化模块(Visualization)的点云查看函数,实现外接设备通过第三方接口与编译环境的连通,完成对空间物体的实时点云化处理与显示(见图24)。

图24 点云实时显示

图25 PCD文件读取

4.2.2 点云文件读取与初步重建

点云数据以PCD(Point Cloud Data)文件(见图25)为常用载体进行储存,PCD的内容以ASCII码的形式展现,方便计算机写入与读取。

由未经后期处理的原始点云数据重建成的三维空间图像如图26所示。从图中可以看出,重建的空间模型大致轮廓存在,但是纹理信息缺失,而且还有严重的数据丢失,导致重建模型图并不完整。

图26 三维重建图像

5 结语

本文在Windows及Linux系统下完成了PCL搭建,指出了配置过程中应注意的多个事项,为尚在PCL环境搭建初学者提供了有效参考。同时,在采用传统SIFT特征点提取算法的基础上,结合FLANN搜索匹配算法对特征点进行匹配,降低了误匹配率,取得了很好的实验结果,但是仍存在数量较小的误匹配,这也是今后研究中需要解决的问题。另外,重建模型纹理细节还不够明显,需要后期进一步优化。

猜你喜欢

特征描述源代码三维重建
人工智能下复杂软件源代码缺陷精准校正
船舶尾流图像的数字化处理和特征描述技术
基于TXL的源代码插桩技术研究
软件源代码非公知性司法鉴定方法探析
目标鲁棒识别的抗旋转HDO 局部特征描述
用于三维点云表示的扩展点特征直方图算法*
基于关系图的无人机影像三维重建
三维重建结合3D打印技术在腔镜甲状腺手术中的临床应用
揭秘龙湖产品“源代码”
多排螺旋CT三维重建在颌面部美容中的应用