基于多台azure kinects的点云采集、配准、相加
本文采用多台Azure kinect实现了对人体的动态捕捉文章目录前言一、多台Azure kinect的配准1、硬件配准2、利用k4arecorder录制二、点云采集三、点云配准1.基于AprilTag的粗配准[1]2.基于彩色ICP的细配准[2]四、点云相加五、开源项目推荐总结参考文献前言如果你是刚接触kinect的小白,建议认真阅读Microsoft给出的官方文档如果你打算自己开发azure
本文采用多台Azure kinect实现了对人体的动态捕捉
文章目录
前言
- 如果你是刚接触kinect的小白,建议认真阅读Microsoft给出的官方文档
- 如果你打算自己开发azure kinect的程序,请参考官方的SDK手册
- 如果你想在win下配置azure kinect的开发环境,请参考我的上一篇文章
- 在linux下配置azure kinect会复杂一些,k4a暂时不支持ubuntu 21.04.建议选择20.04LTS或18.04LTS。官方手册中提供了安装指南,在网上也能搜到一些资料,如点击此处。
- 在本文中,录制视频与生成点云是分开的。 这样做的好处有两点。一是在具体操作时发现如果二者并行,采集速度将会是龟速。二是这里的kinect即使替换为任意的RGB-D相机,该程序仍然可以运行。
- 本文大部分代码与思想基于此文,大感谢!
提示:以下是本篇文章正文内容,下面案例可供参考
一、多台Azure kinect的配准
1、硬件配准
配准硬件相当简单,具体参见此处。如果使用Daisy-chain configuration,你仅需3.5mm的音频线,一端插入sync out,一端连接sync in。如此反复,将多台kinect连接起来。第一台机器会被自动识别为主设备(master device)。你可以使用SDK中自带的viewer进行查看。打开多个viewer窗口来打开多台设备,依次打开从属设备(subordinate device),最后打开主设备。如果你的配置正确,它们会同时开启。
kinect可以用一根usb-c线同时完成供电与传输信号。如果你打算这么做,且线的长度会超过1.5m,推荐使用有源usb-c线。
The Azure Kinect can be powered in two ways:
- The sensor comes with its own USB-C to USB-A cable with power adapter that can used to power the sensor via wall power outlet.
- For capturing on location, you can power the device with a USB-C to USB-C cable verified to supply both the power as well as the data transfer.
2、利用k4arecorder录制
如果你想要体验一下自己写代码的乐趣,强烈推荐这个专栏。
但由于笔者照葫芦画瓢写完之后一不小心删除了整个工程文件,并且心灰意冷直接摆烂…
同时sdk自带的工具k4arecorder也可以实现这个功能。具体的介绍也可以在官方文档中找到。
请注意!
- 使用管理员权限打开终端,不然可能没有权限写入视频文件。
- 如果找不到k4arecorder.exe的命令,将其替换为k4arecorde试试。
- 如果你也像笔者一样,需要一个外部触发来实现设备间的同步,可以将所有设备都设置为从属模式,将头一个设备的sync in连接至你的触发源。
二、点云采集
k4arecorder得到的是一个mkv视频文件,其中包括了RGB图,深度图,以及每个时刻的时间戳信息。我们要做的就是读取各个信息,并将其转换到点云文件中。
for (int i = 0; i < count; i += coord_stride) {
Eigen::Vector3d q(frame.PointCloudData.data()[3 * i + 0] / 1000.0f, frame.PointCloudData.data()[3 * i + 1] / 1000.0f, frame.PointCloudData.data()[3 * i + 2] / 1000.0f);
if (q.z() == 0)
{
continue;
}
// BGR -> RGB
Eigen::Vector3d color{};
color.z() = (double)frame.ColorImage.data()[4 * i + 0] / 255.0;
color.y() = (double)frame.ColorImage.data()[4 * i + 1] / 255.0;
color.x() = (double)frame.ColorImage.data()[4 * i + 2] / 255.0;
if (color.x() == 0 && color.y() == 0 && color.z() == 0)
{
continue;
}
full_cloud[idx]->points_.push_back(q);
full_cloud[idx]->colors_.push_back(color);
}
三、点云配准
关于点云配准的文章在CSDN就能查到很多,在这里就不赘述了。一句话概括:点云配准就是一个用各种方法寻找相机间的旋转矩阵的过程。 需要注意如果直接使用ICP配准,很可能陷入局部最优解中。因此我们引入一个编码标志点(fiducial marker)来判断相机的相对位置,再调用ICP来细化相机的位置。
1.基于AprilTag的粗配准[1]
部分代码如下(示例):
apriltag_detection_info_t info;
info.det = det;
info.cx = calibration.Color.cx; // pixels
info.cy = calibration.Color.cy;
info.fx = calibration.Color.fx; // mm
info.fy = calibration.Color.fy;
info.tagsize = 0.22f; // in meters 按照你的maker大小修改
其中tagsize取决于你的图片尺寸,计算标准如下:
Apriltag还有其他的参数,如果你想要达到更好的效果,不妨花些时间研究一下。
2.基于彩色ICP的细配准[2]
官网提供的函数示例:
RegistrationResult open3d::pipelines::registration::RegistrationGeneralizedICP ( const geometry::PointCloud & source,
const geometry::PointCloud & target,
double max_correspondence_distance,
const Eigen::Matrix4d & init = Eigen::Matrix4d::Identity(),
const TransformationEstimationForGeneralizedICP & estimation = TransformationEstimationForGeneralizedICP(),
const ICPConvergenceCriteria & criteria = ICPConvergenceCriteria()
)
Parameters:
source: 源点云.
target: 目标点云.
max_distance:最大对应点对距离
init 初始变换估计. 默认值: array([[1., 0., 0., 0.], [0., 1., 0., 0.], [0., 0., 1., 0.], [0., 0., 0., 1.]]). (本项目中使用apriltag配准后得到的矩阵)
criteria: 收敛标准.
四、点云相加
两个维度相同的点云相加非常简单,在open3d中,你仅仅需要创建两个指向点云的指针(std::shared_ptr<open3d::geometry::PointCloud>
),然后*cloud_A+=*cloud_B
即可。要注意指针必须指向某个位置,不然会出现segment fault的问题。比如:full_cloud = std::make_shared<open3d::geometry::PointCloud>();
这样指针full_cloud就指向了一个空的点云。
五、开源项目推荐
https://github.com/stytim/k4a-calibration
推荐!实用且好用!不过配置环境较为麻烦,其实如果只是想输出点云文件,可以只安装open3d和sdk,但要修改相应的cmake文件和头文件。
https://github.com/catid/xrcap/tree/master/codecs
此项目实现了windows上的实时人体捕捉,一度让笔者心动不已,但实在没法解决K4a dir not found的问题,最终放弃了。
https://vcl3d.github.io/VolumetricCapture/docs/synchronization/
不多说,看起来就非常炫酷。
总结
其实整个过程还是非常简单的,每个环节都能找到很多前人留下的笔记。笔者从一个两眼一抹黑的c++小白到终于拼拼凑凑做出来,实在是走了很多弯路。Anyway,希望大家都能顺顺利利完成。
参考文献
[1]https://april.eecs.umich.edu/software/apriltag
[2]Jaesik Park, Qian-Yi Zhou, Vladlen Koltun; Proceedings of the IEEE International Conference on Computer Vision (ICCV), 2017, pp. 143-152
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)