Xungerrrr's Blog

用Azure Kinect DK追踪人体运动

人体追踪能怎么玩?Azure Kinect DK上手试玩。

Word count: 1.8kReading time: 6 min
2019/10/08 Share

上次我们在介绍Azure Kinect DK时,提到它包含了一个人体追踪SDK。Kinect人体追踪应该不算新鲜,之前Xbox上的体感游戏就已经用到了Kinect的人体追踪功能。新的Azure Kinect DK将人体追踪功能整合到了一个SDK中,方便开发者对人体追踪数据进行操作。今天我们就来探索一下Azure Kinect DK的人体追踪功能。

一些基本概念

人体追踪关节

每个追踪的关节都有其位置和方向,它们决定了关节自身的坐标系。人体追踪骨架共包含26个关节,层次结构按照从人体中心骨盆(PELVIS)向四肢的流向分布。每个连接(骨骼)将父关节与子关节链接起来。下图演示了关节坐标以及相对于人体的层次结构。

人体索引映射

人体索引映射是一张分割图像,将深度图按照人体划分成不同的区域。它用不同的像素值表示不同的人体,其像素与深度图一一对应。

人体帧包含的内容

人体帧是人体追踪的结果,它包含以下三个关键的部分:

  1. 人体结构的集合
  2. 2D人体索引映射
  3. 生成此结果的输入捕获

人体追踪

使用Azure Kinect DK的人体追踪SDK,可以直接追踪人体骨架,不需要进行额外的训练。先下载和安装人体追踪SDK,然后连接好Kinect设备,就可以开始探索了!

人体追踪演示

安装好SDK后,我们就可以直接运行其附带的小工具来演示追踪过程。工具位于安装目录下的tools/k4abt_simple_3d_viewer.exe。

下面是演示的效果。可以看到,这个程序将3D深度图、人体骨架和人体索引映射同时展示出来,追踪效果相当不错。

人体追踪的操作过程

光看演示还不够,我们还需要了解人体追踪的具体操作过程。下面,我们用C++的API来说明这个过程。一般来说,Azure Kinect DK的人体追踪分为以下步骤:

  1. 打开设备,配置并启动相机

    1
    2
    3
    4
    5
    6
    7
    8
    k4a_device_t device = nullptr;
    VERIFY(k4a_device_open(0, &device), "Open K4A Device failed!");

    // Start camera. Make sure depth camera is enabled.
    k4a_device_configuration_t deviceConfig = K4A_DEVICE_CONFIG_INIT_DISABLE_ALL;
    deviceConfig.depth_mode = K4A_DEPTH_MODE_WFOV_2X2BINNED;
    deviceConfig.color_resolution = K4A_COLOR_RESOLUTION_OFF;
    VERIFY(k4a_device_start_cameras(device, &deviceConfig), "Start K4A cameras failed!");
  2. 创建人体追踪器

    1
    2
    3
    4
    5
    6
    7
    8
    9
    // Get calibration information
    k4a_calibration_t sensorCalibration;
    VERIFY(k4a_device_get_calibration(device, deviceConfig.depth_mode, deviceConfig.color_resolution, &sensorCalibration),
    "Get depth camera calibration failed!");

    // Create Body Tracker
    k4abt_tracker_t tracker = nullptr;
    k4abt_tracker_configuration_t tracker_config = K4ABT_TRACKER_CONFIG_DEFAULT;
    VERIFY(k4abt_tracker_create(&sensorCalibration, tracker_config, &tracker), "Body tracker initialization failed!");
  3. 从设备中获取捕获

    1
    2
    k4a_capture_t sensorCapture = nullptr;
    k4a_wait_result_t getCaptureResult = k4a_device_get_capture(device, &sensorCapture, 0); // timeout_in_ms is set to 0
  4. 将捕获排入队列并弹出结果(人体帧)

    人体追踪器在内部维护了一个输入队列和一个输出队列,以便更有效地以异步方式处理Azure Kinect DK捕获。我们只需要将捕获排入队列,然后从队列弹出结果,就能获得一个人体帧结果。

    1
    2
    3
    4
    5
    6
    // Add capture to tracker process queue
    k4a_wait_result_t queueCaptureResult = k4abt_tracker_enqueue_capture(tracker, sensorCapture, 0);

    // Pop Result from Body Tracker
    k4abt_frame_t bodyFrame = nullptr;
    k4a_wait_result_t popFrameResult = k4abt_tracker_pop_result(tracker, &bodyFrame, 0); // timeout_in_ms is set to 0
  5. 访问人体帧数据

    下面的例子显示了如何访问人体帧中的原始捕获。

    1
    2
    // Obtain original capture that generates the body tracking result
    k4a_capture_t originalCapture = k4abt_frame_get_capture(bodyFrame);

简单应用:跳跃分析

示例工程jump_analysis_sample展示了一个有趣的应用。这个应用通过分析跳跃过程中的人体帧数据,计算出跳跃高度、起跳下蹲距离、起跳速度和下蹲膝盖角度等信息。同时,根据这些信息,它还展示出在准备起跳时和在最高点时的状态图,以及整个跳跃过程的动画回放。

速度

如何计算速度是整个应用的关键之处。通过速度信息,结合跳跃运动的物理特征,可以获得运动过程各个关键点的位置,例如起跳点和落地点、最高点和最低点。由于人体追踪产生的每一个人体帧都包含所有关节的三维坐标和时间戳信息,该应用巧妙地利用了高度(y方向)对时间的一次导数来计算出垂直速度信息。

1
2
3
4
5
6
7
8
// First derivate of height array
std::vector<float> heightDerivative = DSP::FirstDerivate(heightFiltered);

// First derivate of timestamp array
std::vector<float> timeFirstDerivate = DSP::FirstDerivate(timestamp);

// Calculate unit velocity by dh/dt
std::vector<float> velocityY = DSP::DivideTwoArrays(heightDerivative, timeFirstDerivate);

有了速度信息之后,可以进一步结合跳跃运动的物理特征,来得出一些有趣的信息。例如,上升过程中最大的速度即为起跳速度。

1
2
3
4
5
6
// Maximum velocity
IndexValueTuple maxVelocityInMmPerUsec = DSP::FindMaximum(velocityY, 0, velocityY.size());

const float UsecToSecond = 1e-6f;
// Push off velocity
jumpResults.PushOffVelocity = maxVelocityInMmPerUsec.Value / UsecToSecond;

体感控制

利用关节信息,还可以用动作来控制程序运行。在这个应用中,只要将双手举过头顶,就可以控制跳跃动作捕获的开始和结束。原理很简单,将手腕关节和头部的y坐标值进行比较就可以了。

1
2
3
// Notice: y direction is pointing towards the ground! So jointA.y < jointB.y means jointA is higher than jointB
bool bothHandsAreRaised = leftWristJoint.xyz.y < headJoint.xyz.y &&
rightWristJoint.xyz.y < headJoint.xyz.y;

演示

连接好Kinect,运行程序,看到下方的提示文本,就可以开始尝试啦。

将双手举过头顶,开始录制。完成跳跃后,再次将双手举过头顶结束录制。屏幕上会显示跳跃数据、起跳点和最高点的关键帧以及跳跃回放。

应用场景

从上面的例子可以看到,Azure Kinect DK中的人体追踪SDK可以直接用来追踪人体骨架、识别人体位置,能够实时生成关节的三维坐标和方位。不管是离线使用,还是结合Azure使用,都有着丰富的应用场景。

  • 运动员动作分析

    在运动员的训练中,利用人体追踪数据分析运动动作的准确性和有效性,帮助运动员提升训练成绩。例如,上述的跳跃分析程序就能够用于跳高运动员的动作分析。在训练的时候,运动员可以设定训练目标,例如平均起跳速度、平均跳跃高度、最大跳跃高度等等,然后用Azure Kinect进行人体追踪,多次训练之后计算出平均结果和最优成绩。利用录制功能,运动员还能够结合多次跳跃的回放,分析出最佳起跳点、最佳弧线、最佳动作等等。

  • 病人情况监测

    在医院,监测卧床病人的肢体状况,及时通知医护人员。利用关节的坐标位置,可以判断病人的动作,实现自动化监测与预警。例如,当病人的手腕关节高于头部一定的高度时,可以认为病人举起了手,病人可能需要寻求医护人员的帮助;当病人的部分关节低于床铺高度时,可认为病人有摔下床的风险,应及时通知医护人员。

CATALOG
  1. 1. 一些基本概念
    1. 1.1. 人体追踪关节
    2. 1.2. 人体索引映射
    3. 1.3. 人体帧包含的内容
  2. 2. 人体追踪
    1. 2.1. 人体追踪演示
    2. 2.2. 人体追踪的操作过程
    3. 2.3. 简单应用:跳跃分析
      1. 2.3.1. 速度
      2. 2.3.2. 体感控制
      3. 2.3.3. 演示
  3. 3. 应用场景