I am using the Azure DK to read an MKV file where I am able to extract the RGBA and corresponding depth image for each frame. Thereafter I use the body tracker to locate and track people using the depth image. At the moment, I am able to generate a body index map and even convert it to the colour camera space as shown below.
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);
}
I am currently stuck on how to:
Use the generated body index map to crop/segment/draw out the colour image in order to extract the visual representation of the body. I am pretty much looking to replicate this; the portion with the RGBA images
Convert the cropped image into a 2D RGBA image
Any help will be greatly appreciated :)
After messing around, I finally managed to resolve this. I switched over to OpenCV for image manipulation.
First, I converted body_index_in_colour_space
to 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();
}
I converted the kinect BGRA image to OpenCV Mat as well in a similar manner by changing the flag from CV_8UC1
to CV_8UC4
. Thereafter I simply drew the index map on top of the colour image.
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;
}