Azure Kinect 使用 Body 索引图裁剪 Body

Azure Kinect Crop Out Body Using Body Index Map

我正在使用 Azure DK 读取 MKV 文件,我可以在其中提取每帧的 RGBA 和相应的深度图像。此后,我使用 body 跟踪器使用深度图像定位和跟踪人员。目前,我能够生成 body index map 甚至将其转换为彩色相机 space,如下所示。

k4a::image extract_body_index_map(tracker& object_tracker)
{
    k4a::image body_index_map = k4a::image();

    k4abt::frame body_frame = object_tracker.pop_result();

    if (body_frame != nullptr)
    {
        uint32_t bodies = body_frame.get_num_bodies();

        cout << "Bodies Found: " << bodies << "\n";

        for (uint32_t index = 0; index < bodies; ++index)
        {
            k4abt_body_t body = body_frame.get_body(index);

            cout << "\tPERSON: " << body.id << "\n";
            body_index_map = body_frame.get_body_index_map();
        }
    }
    else { cerr << "ERROR: Body Pop Out Timeout\n\n"; }

    return body_index_map;
}

k4a::image convert_body_index_map_to_colour(k4a::image& body_index_map, k4a::image& depth, k4a::image& colour, k4a_transformation_t transformation)
{
    k4a_image_t depth_image_in_colour_space = nullptr;

    k4a_result_t result = k4a_image_create(K4A_IMAGE_FORMAT_DEPTH16, 
        colour.get_width_pixels(), colour.get_height_pixels(), 
        colour.get_width_pixels() * (int)sizeof(uint16_t), &depth_image_in_colour_space);

    if (result == K4A_RESULT_FAILED)
    {
        cerr << "ERROR: Failed to create depth image in colour space\n";
        return nullptr;
    }

    k4a_image_t body_index_in_colour_space = nullptr;

    result = k4a_image_create(K4A_IMAGE_FORMAT_CUSTOM8,
        colour.get_width_pixels(), colour.get_height_pixels(),
        colour.get_width_pixels() * (int)sizeof(uint8_t), &body_index_in_colour_space);

    if (result == K4A_RESULT_FAILED)
    {
        cerr << "ERROR: Failed to create body index map in colour space\n";
        return nullptr;
    }


    result = k4a_transformation_depth_image_to_color_camera_custom(transformation, depth.handle(),
        body_index_map.handle(), depth_image_in_colour_space, body_index_in_colour_space,
        K4A_TRANSFORMATION_INTERPOLATION_TYPE_NEAREST, K4ABT_BODY_INDEX_MAP_BACKGROUND);

    if (result == K4A_RESULT_FAILED)
    {
        cerr << "ERROR: Failed to transform body index map to colour space\n";
        return nullptr;
    }

    return k4a::image(body_index_in_colour_space);
}

我目前不知道如何:

  1. 使用生成的 body 索引图 crop/segment/draw 出彩色图像,以便提取 body 的视觉表示。我非常想复制 thisRGBA图像部分

  2. 将裁剪后的图像转换为 2D RGBA 图像

任何帮助将不胜感激:)

折腾了一圈,终于解决了。 我切换到 OpenCV 进行图像处理。

首先,我将body_index_in_colour_space转换为OpenCV Mat

Mat convertToMat(k4a::image kinect_image)
{
    uint8_t* pixel_data = kinect_image.get_buffer();

    if (pixel_data != nullptr) return Mat(kinect_image.get_height_pixels(), kinect_image.get_width_pixels(), CV_8UC4, (void*)pixel_data, Mat::AUTO_STEP);

    return Mat();
}

我通过将标志从 CV_8UC1 更改为 CV_8UC4,以类似的方式将 kinect BGRA 图像转换为 OpenCV Mat。然后我简单地在彩色图像上画了索引图。

Mat drawIndexMapOnColourImage(Mat indexMap, Mat colour)
{
    Mat result;
    colour.copyTo(result);

    //TODO: Not efficient, fix this
    for(size_t row = 0; row < indexMap.rows; ++row)
        for (size_t col = 0; col < indexMap.cols; ++col)
        {
            if ((int)indexMap.at<uchar>(row, col) == 255) continue; // ignore background

            result.at<Vec4b>(row, col) = 150;
        }

    return result;
}