无需Kinect坐标映射器,如何将3D骨骼关节映射回2D彩色图像?
关于Kinect骨骼3D转彩色2D图像的映射问题
你完全说对了——要把深度相机空间里的3D骨骼关节映射到彩色图像的2D坐标,必须先完成从深度相机3D空间到彩色相机3D空间的转换,因为Kinect的深度相机和彩色相机是物理上分离的两个模块,位置、角度都有偏移,不做空间对齐的话,映射出来的2D坐标会完全错位。
如何获取深度→彩色的变换矩阵?
不用自己手动推导!Kinect SDK已经帮你做好了硬件校准,直接就能拿到这个刚体变换矩阵(包含旋转和平移信息的4x4齐次矩阵):
- 如果你用的是Kinect v2:可以调用
CoordinateMapper类的GetDepthCameraToColorCameraTransform()方法,直接获取深度相机到彩色相机的空间变换矩阵。哪怕你不想用CoordinateMapper做完整的2D映射,这个矩阵是可以单独提取使用的。 - 如果你用的是Kinect v1:对应的是
NuiImageCamera类里的相关参数,比如通过GetColorPixelCoordinatesFromDepthPixel()的底层逻辑,可以分离出旋转和平移的外参。
完整的3D→2D映射步骤(不用CoordinateMapper的完整流程)
结合你提到的第一步,补全后的完整流程是:
- 空间坐标转换:将深度相机空间下的3D关节点(齐次坐标格式为
[X, Y, Z, 1]),和刚才拿到的深度→彩色变换矩阵相乘,得到彩色相机空间下的3D坐标[X', Y', Z', 1]。 - 透视投影到2D:利用彩色相机的内参(焦距
fx/fy、主点坐标cx/cy),通过透视投影公式计算2D坐标:
内参同样可以从SDK获取:比如Kinect v2里通过u = fx * (X' / Z') + cx v = fy * (Y' / Z') + cyColorFrameSource.FrameDescription拿到分辨率,再结合CoordinateMapper的内参参数提取,或者直接用SDK提供的投影辅助方法。 - 像素坐标修正:把计算出的
u、v值转换成彩色图像的实际像素坐标,注意要确保坐标在图像分辨率范围内(比如彩色图像是1920×1080的话,u需在01919之间,`v`在01079之间),超出范围的关节点可以做裁剪或忽略。
额外提醒
如果你想彻底绕开SDK的CoordinateMapper,自己手动标定两个相机的外参,理论上可行,但非常麻烦——需要用棋盘格等标定物分别标定深度、彩色相机的内参,再通过对应点计算外参。但这远不如SDK提供的出厂校准参数准确,毕竟Kinect在生产时已经完成了专业的硬件校准。
内容的提问来源于stack exchange,提问作者Chien Duong
相关产品推荐
相关产品推荐

