原文地址:http://www.jantime.com/2019/04/15/hololens开发%ef%bc%9a2d-app获取头部位姿信息/
近日在项目上遇到一个需求:使用HoloLens采集RGBD和位姿信息,用于深度学习计算。后面的深度学习不用管,只需负责产生数据即可。把数据拆开来看,分三部分:RGB影像、Depth数据和相机(头部,暂忽略相机和头部之间的偏移)位置姿态。
采集RGB影像的方法有很多,Unity、OpenCV等都提供了接口,可非常方便的采集摄像头的影像数据。
采集Depth数据。HoloLens内置一个ToF深度传感器,用于测量周围环境。在旧版本(RS4以前)的HoloLens系统中,是没有提供接口的。在RS4版本中,官方增加了Research模式,用于采集传感器数据,同时官方提供了一个Example,叫做HoloLensForCV(该工程我们后续分析),在GitHub上可以找到,采用C++ /cx编写。通过编译运行该工程,了解到需要使用微软本家的MF框架来采集传感器数据。
再看采集相机位姿信息。这对于使用Unity开发HoloLens应用的程序员来说太简单了,Unity的Camera会自动和HoloLens绑定,只要实时获取Camera的位姿即可,甚至四元数转欧拉角的过程都可以省去。
这时候,问题来了,因为位姿和RGBD需一一对应,那我只能在一个APP里实现采集功能。应该写2D APP还是Unity 3D APP呢?
2D APP:可以采集RGBD数据,但是如何采集位姿数据?
3D APP:可以方便的采集位姿数据,如何采集RGBD数据?
写了这么多废话,以上就是我为什么要通过2D APP获取头部位姿信息。(Unity 3D APP也能实现采集Depth数据,有两种方式:一、采用MF.net这个框架;二、内嵌UWP代码。这里暂不讨论。)
根据从网上看到的相关文章,再加上我个人的理解,在HoloLens上运行的程序应该都是3D形式。2D APP运行在系统的一个3D程序之上(我们假定它叫:explorer3D),而在运行我们自己写的3D APP时,系统则不再运行explorer3D。
既然2D APP也是运行在3D环境内,那3D APP的某些接口那应该也能用。(HoloLens 在不运行任何3D程序时,通过Windows Device Portal或Rest API都能获取到相机的位姿)。
下面进入正题,贴上相关代码(基于C++ /cx)。该方法可能不是唯一方法。
Windows::Graphics::Holographic::HolographicDisplay^ defaultHolographicDisplay= HolographicDisplay::GetDefault();
Windows::Perception::Spatial::SpatialLocator^ m_Locator= defaultHolographicDisplay->SpatialLocator;
Windows::Perception::Spatial::SpatialStationaryFrameOfReference^ m_stationaryReferenceFrame= m_Locator->CreateStationaryFrameOfReferenceAtCurrentLocation();
以上为初始化代码,三个对象只需获取一次。
Windows::Perception::PerceptionTimestamp^aa=Windows::Perception::PerceptionTimestampHelper::FromSystemRelativeTargetTime(TimeSpan());
SpatialLocation^ pos= m_Locator->TryLocateAtTimestamp(aa, m_stationaryReferenceFrame->CoordinateSystem);
SpatialLocation里包含了头部的位置和姿态信息。
几个类的作用就不再赘述了,可以直接翻看API文档。