三维重建流水线,描述了从获取原始数据到重建三维网格数据的流程及其中涉及到的算法,它是一系列相关技术的总称。首先使用OpenNI作为设备驱动,通过Kinect采集了深度数据。基于KinectFusion算法构建了三维重建流水线的数据融合部分。最后,移植和扩展了 PCL中基于GPU的在线移动立方体重建。KinectFusion算法已有多种开源实现,三维重建流水线程序,基于开源项目kinfu_remake及PCL开发。
Kinect具有一枚RGB摄像头、一枚红外摄像头以及一个红外发射器,它可以以最高30fps的侦率获取640*480分辨率的深度和彩色数据。其中深度数据的获取用的是Primesensor的光编码技术,红外发射器投射830nm红外光,通过散片和光栅在物体上形成散斑,红外摄像头读取散斑,对照模板计算出物体相对于摄像头的距离,获取深度数据。红外摄像头覆盖有一个允许830nm红外线通过的滤镜,可以显著减少其他红外设备的干扰。尽管如此,阳光中的红外线仍然会对Kinect产生干扰,因此该设备比较适合在室内环境中使用。
由于Kiiiect SDK只能在Windows平台运行,不满足对于跨平台性的要求,因此使用开源驱动OpenNI作为深度摄像机的驱动程序。数据采集模块封装为DepthSensor类进行管理。
NI类负责对设备上下文、生产节点和元数据进行管理,它和DepthSensor类为聚合关系,其中depth和image分别为深度数据节点和图像数据节点,context为设备上下文对象。
DepthSensor类包含四个公有的方法,重载的两个open()函数分别用于进行实时拍摄模式和数据重放模式下的初始化工作。首先初始化设备上下文。然后判断当前的数据采集模式,对于实时拍摄模式,加载并执行XML配置文件,创建预定义的生产节点。默认包含深度数据节点,RGB数据节点和录制节点。对于数据重放模式,首先创建播放节点,然后加载待播放文件,注册到达文件结尾事件的回调函数,获取录像包含的总侦数。根据用户需求,指定关键侦W进行关键侦回放。至此,初始化完成。调用FindExistingNode()函数将全部已始化节点找回,分别赋值给depth和image节点进行管理。随后,执行StartGeneratingAll()函数,等待数据交换层下达更新请求。
当主界面更新定时器触发时,数据交换层调用readframe()方法请求更新数据,数据就绪后,操作深度数据节点和RGB数据节点读取元数据,通过processIncomingG()方法,将元数据取回并会根据图像类型转换为OpenCV矩阵格式。对于深度数据,创建16位单通道矩阵存放深度元数据,并通过出参out_depth将数据传递到数据交换层。彩色数据则为8位3通道数据,通过出参out_image进行传递。此外,可根据需要,调用filter()方法对采集到的深度数据进行过滤,设定深度数据的最大值与最小值,对于不在范围内的数据进行置0处理,可进行初步的背景移除。