您现在访问的是微软AZURE全球版技术文档网站,若需要访问由世纪互联运营的MICROSOFT AZURE中国区技术文档网站,请访问 https://docs.azure.cn.

快速入门:生成 Azure Kinect 人体跟踪应用程序Quickstart: Build an Azure Kinect body tracking application

想要开始使用人体跟踪 SDK?Getting started with the Body Tracking SDK? 本快速入门可帮助你启动并运行人体跟踪!This quickstart will get you up and running with body tracking! 可以在此 Azure-Kinect-Sample 存储库中找到更多示例。You can find more examples in this Azure-Kinect-Sample repo.

先决条件Prerequisites

头文件Headers

人体跟踪使用单个头文件 k4abt.hBody tracking uses a single header, k4abt.h. 请包含此头文件以及 k4a.hInclude this header in addition to k4a.h. 确保所选的编译器已针对传感器 SDK 和人体跟踪 SDK libinclude 文件夹进行设置。Make sure your compiler of choice is set up for both the Sensor SDK and the Body Tracking SDK lib and include folders. 还需要链接到 k4a.libk4abt.lib 文件。You also need to link to k4a.lib and k4abt.lib files. 运行该应用程序需要 k4a.dllk4abt.dllonnxruntime.dlldnn_model.onnx 位于应用程序执行路径中。Running the application requires k4a.dll, k4abt.dll, onnxruntime.dll, and dnn_model.onnx to be in the applications execution path.

#include <k4a/k4a.h>
#include <k4abt.h>

打开设备并启动相机Open device and start the camera

第一个人体跟踪应用程序假设已将单个 Azure Kinect 设备连接到电脑。Your first body tracking application assumes a single Azure Kinect device connected to the PC.

人体跟踪基于传感器 SDK。Body tracking builds on the Sensor SDK. 若要使用人体跟踪,首先需要打开并配置设备。To use body tracking, you first need to open and configure the device. 使用 k4a_device_open() 函数打开设备,然后使用 k4a_device_configuration_t 对象对其进行配置。Use the k4a_device_open() function to open the device and then configure it with a k4a_device_configuration_t object. 为获得最佳结果,请将深度模式设置为 K4A_DEPTH_MODE_NFOV_UNBINNEDK4A_DEPTH_MODE_WFOV_2X2BINNEDFor best results set the depth mode to K4A_DEPTH_MODE_NFOV_UNBINNED or K4A_DEPTH_MODE_WFOV_2X2BINNED. 如果深度模式设置为 K4A_DEPTH_MODE_OFFK4A_DEPTH_MODE_PASSIVE_IR,人体跟踪器将无法运行。The body tracker will not run if the depth mode is set to K4A_DEPTH_MODE_OFF or K4A_DEPTH_MODE_PASSIVE_IR.

此页上可以找到有关查找和打开设备的详细信息。You can find more information on finding and opening the device on this page.

可在以下页面上找到有关 Azure Kinect 深度模式的详细信息:硬件规范k4a_depth_mode_t 枚举。You can find more information on Azure Kinect depth modes on these pages: hardware specification and k4a_depth_mode_t enumerations.

k4a_device_t device = NULL;
k4a_device_open(0, &device);

// 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_NFOV_UNBINNED;
deviceConfig.color_resolution = K4A_COLOR_RESOLUTION_OFF;
k4a_device_start_cameras(device, &deviceConfig);

创建跟踪器Create the tracker

获取人体跟踪结果的第一步是创建人体跟踪器。The first step in getting body tracking results is to create a body tracker. 该跟踪器需要 k4a_calibration_t 传感器校准结构。It needs the sensor calibration k4a_calibration_t structure. 可以使用 k4a_device_get_calibration() 函数查询传感器校准。The sensor calibration can be queried using the k4a_device_get_calibration() function.

k4a_calibration_t sensor_calibration;
k4a_device_get_calibration(device, deviceConfig.depth_mode, deviceConfig.color_resolution, &sensor_calibration);

k4abt_tracker_t tracker = NULL;
k4abt_tracker_configuration_t tracker_config = K4ABT_TRACKER_CONFIG_DEFAULT;
k4abt_tracker_create(&sensor_calibration, tracker_config, &tracker);

从 Azure Kinect 设备获取捕获Get captures from the Azure Kinect device

此页上可以找到有关检索图像数据的详细信息。You can find more information on retrieving image data on this page.

// Capture a depth frame
k4a_device_get_capture(device, &capture, TIMEOUT_IN_MS);

将捕获排入队列并弹出结果Enqueue the capture and pop the results

跟踪器在内部维护一个输入队列和一个输出队列,以便更有效地以异步方式处理 Azure Kinect DK 捕获。The tracker internally maintains an input queue and an output queue to asynchronously process the Azure Kinect DK captures more efficiently. 下一步是使用 k4abt_tracker_enqueue_capture() 函数将新的捕获添加到输入队列。The next step is to use the k4abt_tracker_enqueue_capture() function to add a new capture to the input queue. 使用 k4abt_tracker_pop_result() 函数弹出输出队列的结果。Use the k4abt_tracker_pop_result() function to pop a result from the output queue. 超时值与应用程序相关,控制队列等待时间。The timeout value is dependent on the application and controls the queueing wait time.

第一个人体跟踪应用程序使用实时处理模式。Your first body tracking application uses the real-time processing pattern. 有关其他模式的详细说明,请参阅获取人体跟踪结果Refer to get body tracking results for a detailed explanation of the other patterns.

k4a_wait_result_t queue_capture_result = k4abt_tracker_enqueue_capture(tracker, sensor_capture, K4A_WAIT_INFINITE);
k4a_capture_release(sensor_capture); // Remember to release the sensor capture once you finish using it
if (queue_capture_result == K4A_WAIT_RESULT_FAILED)
{
    printf("Error! Adding capture to tracker process queue failed!\n");
    break;
}

k4abt_frame_t body_frame = NULL;
k4a_wait_result_t pop_frame_result = k4abt_tracker_pop_result(tracker, &body_frame, K4A_WAIT_INFINITE);
if (pop_frame_result == K4A_WAIT_RESULT_SUCCEEDED)
{
    // Successfully popped the body tracking result. Start your processing
    ...

    k4abt_frame_release(body_frame); // Remember to release the body frame once you finish using it
}

访问人体跟踪结果数据Access the body tracking result data

每个传感器捕获的人体跟踪结果存储在人体帧 k4abt_frame_t 结构中。The body tracking results for each sensor capture are stored in a body frame k4abt_frame_t structure. 每个人体帧包含三个重要组成部分:人体结构的集合、2D 人体索引映射和输入捕获。Each body frame contains three key components: a collection of body structs, a 2D body index map, and the input capture.

第一个人体跟踪应用程序只访问检测到人体数。Your first body tracking application only accesses the number of detected bodies. 有关人体帧中的数据的详细说明,请参阅访问人体帧中的数据Refer to access data in body frame for detailed explanation of data in a body frame.

size_t num_bodies = k4abt_frame_get_num_bodies(body_frame);
printf("%zu bodies are detected!\n", num_bodies);

清除Clean up

最后一步是关闭人体跟踪器并释放人体跟踪对象。The final step is to shut down the body tracker and release the body tracking object. 此外,还需要停止并关闭设备。You also need to stop and close the device.

k4abt_tracker_shutdown(tracker);
k4abt_tracker_destroy(tracker);
k4a_device_stop_cameras(device);
k4a_device_close(device);

完整源代码Full source

#include <stdio.h>
#include <stdlib.h>

#include <k4a/k4a.h>
#include <k4abt.h>

#define VERIFY(result, error)                                                                            \
    if(result != K4A_RESULT_SUCCEEDED)                                                                   \
    {                                                                                                    \
        printf("%s \n - (File: %s, Function: %s, Line: %d)\n", error, __FILE__, __FUNCTION__, __LINE__); \
        exit(1);                                                                                         \
    }                                                                                                    \

int main()
{
    k4a_device_t device = NULL;
    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_NFOV_UNBINNED;
    deviceConfig.color_resolution = K4A_COLOR_RESOLUTION_OFF;
    VERIFY(k4a_device_start_cameras(device, &deviceConfig), "Start K4A cameras failed!");

    k4a_calibration_t sensor_calibration;
    VERIFY(k4a_device_get_calibration(device, deviceConfig.depth_mode, deviceConfig.color_resolution, &sensor_calibration),
        "Get depth camera calibration failed!");

    k4abt_tracker_t tracker = NULL;
    k4abt_tracker_configuration_t tracker_config = K4ABT_TRACKER_CONFIG_DEFAULT;
    VERIFY(k4abt_tracker_create(&sensor_calibration, tracker_config, &tracker), "Body tracker initialization failed!");

    int frame_count = 0;
    do
    {
        k4a_capture_t sensor_capture;
        k4a_wait_result_t get_capture_result = k4a_device_get_capture(device, &sensor_capture, K4A_WAIT_INFINITE);
        if (get_capture_result == K4A_WAIT_RESULT_SUCCEEDED)
        {
            frame_count++;
            k4a_wait_result_t queue_capture_result = k4abt_tracker_enqueue_capture(tracker, sensor_capture, K4A_WAIT_INFINITE);
            k4a_capture_release(sensor_capture); // Remember to release the sensor capture once you finish using it
            if (queue_capture_result == K4A_WAIT_RESULT_TIMEOUT)
            {
                // It should never hit timeout when K4A_WAIT_INFINITE is set.
                printf("Error! Add capture to tracker process queue timeout!\n");
                break;
            }
            else if (queue_capture_result == K4A_WAIT_RESULT_FAILED)
            {
                printf("Error! Add capture to tracker process queue failed!\n");
                break;
            }

            k4abt_frame_t body_frame = NULL;
            k4a_wait_result_t pop_frame_result = k4abt_tracker_pop_result(tracker, &body_frame, K4A_WAIT_INFINITE);
            if (pop_frame_result == K4A_WAIT_RESULT_SUCCEEDED)
            {
                // Successfully popped the body tracking result. Start your processing

                size_t num_bodies = k4abt_frame_get_num_bodies(body_frame);
                printf("%zu bodies are detected!\n", num_bodies);

                k4abt_frame_release(body_frame); // Remember to release the body frame once you finish using it
            }
            else if (pop_frame_result == K4A_WAIT_RESULT_TIMEOUT)
            {
                //  It should never hit timeout when K4A_WAIT_INFINITE is set.
                printf("Error! Pop body frame result timeout!\n");
                break;
            }
            else
            {
                printf("Pop body frame result failed!\n");
                break;
            }
        }
        else if (get_capture_result == K4A_WAIT_RESULT_TIMEOUT)
        {
            // It should never hit time out when K4A_WAIT_INFINITE is set.
            printf("Error! Get depth frame time out!\n");
            break;
        }
        else
        {
            printf("Get depth capture returned error: %d\n", get_capture_result);
            break;
        }

    } while (frame_count < 100);

    printf("Finished body tracking processing!\n");

    k4abt_tracker_shutdown(tracker);
    k4abt_tracker_destroy(tracker);
    k4a_device_stop_cameras(device);
    k4a_device_close(device);

    return 0;
}

后续步骤Next steps