Démarrage rapide : Créer une application de suivi des corps Azure Kinect

Vous débutez avec le SDK Suivi des corps ? Ce guide de démarrage rapide va vous aider à devenir opérationnel avec le suivi des corps. Vous trouverez d’autres exemples dans le dépôt Azure-Kinect-Sample.

Prérequis

En-têtes

Le suivi des corps utilise un seul en-tête : k4abt.h. Incluez cet en-tête en plus de k4a.h. Veillez à ce que le compilateur que vous avez choisi est configuré pour les dossiers lib et include des SDK Capteur et Suivi des corps. Vous devez aussi établir un lien avec les fichiers k4a.lib et k4abt.lib. L’exécution de l’application exige la présence de k4a.dll, k4abt.dll, onnxruntime.dll et dnn_model.onnx dans le chemin d’exécution de l’application.

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

Ouvrir l’appareil et démarrer la caméra

Pour votre première application de suivi des corps, un seul appareil Azure Kinect est censé être connecté au PC.

Le suivi des corps repose sur le SDK Capteur. Pour utiliser le suivi des corps, vous devez d’abord ouvrir et configurer l’appareil. Utilisez la fonction k4a_device_ope() pour ouvrir l’appareil et le configurer ensuite avec un objet k4a_device_configuration_t. Pour de meilleurs résultats, définissez le mode de profondeur sur K4A_DEPTH_MODE_NFOV_UNBINNED ou K4A_DEPTH_MODE_WFOV_2X2BINNED. L’outil de suivi des corps ne s’exécute pas si le mode de profondeur est défini sur K4A_DEPTH_MODE_OFF ou K4A_DEPTH_MODE_PASSIVE_IR.

Vous trouverez des informations complémentaires sur la recherche et l’ouverture de l’appareil dans cette page.

Les modes de profondeur d’Azure Kinect sont décrits de façon plus détaillée dans les pages suivantes : spécification matérielle et énumérations k4a_depth_mode_t.

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);

Créer le dispositif de suivi

Pour obtenir les résultats du suivi des corps, vous devez dans un premier temps créer un dispositif de suivi des corps. Pour cela, vous avez besoin de la structure d’étalonnage de capteur k4a_calibration_t. L’étalonnage de capteur peut être interrogé à l’aide de la fonction k4a_device_get_calibration().

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);

Obtenir les captures de l’appareil Azure Kinect

Vous trouverez des informations complémentaires sur la récupération de données d’image dans cette page.

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

Empiler la capture et dépiler les résultats

Le dispositif de suivi gère en interne une file d’attente d’entrée et une file d’attente de sortie pour traiter de manière asynchrone et plus efficace les captures d’Azure Kinect DK. L’étape suivante consiste à utiliser la fonction k4abt_tracker_enqueue_capture() pour ajouter une nouvelle capture à la file d’attente d’entrée. Utilisez la fonction k4abt_tracker_pop_result() pour dépiler un résultat de la file d’attente de sortie. La valeur de délai d’attente dépend de l’application et contrôle le temps d’attente de mise en file d’attente.

Votre première application de suivi des corps utilise le modèle de traitement en temps réel. Pour obtenir une description détaillée des autres modèles, consultez Obtenir les résultats du suivi des corps.

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
}

Accéder aux données de résultat du suivi des corps

Les résultats du suivi des corps pour chaque capture de capteur sont stockés dans une structure de trame corporelle k4abt_frame_t. Chaque trame corporelle est constituée de trois composantes clés : une collection de structures corporelles, un mappage d’index de corps 2D et la capture d’entrée.

Votre première application de suivi des corps accède uniquement au nombre de corps détectés. Pour obtenir une description détaillée des données contenues dans une trame corporelle, consultez Accéder aux données d’une trame corporelle.

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

Nettoyer

La dernière étape consiste à arrêter le dispositif de suivi des corps et à libérer l’objet de suivi des corps. Vous devez aussi arrêter et fermer l’appareil.

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

Source complète

#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;
}

Étapes suivantes