Skip to content

Commit c0b8e37

Browse files
RoseFlunderStuart Alldritt
authored andcommitted
Add body index map image publishing (opencv#81)
* Add body index map image publishing * Change body index map image to mono8 format * Fixed small syntax error * Added topic description in usage.md * Fixed typos in usage.md
1 parent 55dec73 commit c0b8e37

File tree

4 files changed

+116
-10
lines changed

4 files changed

+116
-10
lines changed

docs/usage.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ The node emits a variety of topics into its namespace.
5252
- `ir/camera_info` (`sensor_msgs::CameraInfo`) : Calibration information for the infrared camera, converted from the Azure Kinect Sensor SDK format. Since the depth camera and infrared camera are physically the same camera, this `camera_info` is a copy of the camera info published for the depth camera.
5353
- `imu` (`sensor_msgs::Imu`) : The intrinsics-corrected IMU sensor stream, provided by the Azure Kinect Sensor SDK. The sensor SDK automatically corrects for IMU intrinsics before sensor data is emitted.
5454
- `body_tracking_data` (`visualization_msgs::MarkerArray`) : Topic for receiving body tracking data. Each message contains all joints for all bodies for the most recent depth image. The markers are grouped by the [body id](https://microsoft.github.io/Azure-Kinect-Body-Tracking/release/0.9.x/structk4abt__body__t.html#a38fed6c7125f92b41165ffe2e1da9dd4) and the joints are in the same order as in the [joint enum of body tracking sdk](https://microsoft.github.io/Azure-Kinect-Body-Tracking/release/0.9.x/group__btenums.html#ga5fe6fa921525a37dec7175c91c473781). The id field of a marker is calculated by: `body_id * 100 + joint_index` where body_id is the corresponding body id from the body tracking sdk and the joint index is analogue to enum value for joints in the body tracking sdk. Subscribers can calculate the body.id by `floor(marker.id / 100)` and the joint_index by `marker.id % 100`.
55+
- `body_index_map/image_raw` (`sensor_msgs::Image`) : The [body index map](https://docs.microsoft.com/de-de/azure/Kinect-dk/body-index-map) represented as mono8 image with a background value of 255.
56+
Up until body id 254 the pixel values of detected bodies will be equal to their corresponding body id. Afterwards the pixel value of detected bodies will be calculated as `body_id % 255` and therefore can only be used for segmentation without a relation to the body id.
5557

5658
## Azure Kinect Developer Kit Calibration
5759

include/azure_kinect_ros_driver/k4a_ros_device.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,10 @@ class K4AROSDevice
6565

6666
#if defined(K4A_BODY_TRACKING)
6767
k4a_result_t getBodyMarker(const k4abt_body_t& body, visualization_msgs::MarkerPtr marker_msg, int jointType, ros::Time capture_time);
68+
69+
k4a_result_t getBodyIndexMap(const k4abt::frame& body_frame, sensor_msgs::ImagePtr body_index_map_image);
70+
71+
k4a_result_t renderBodyIndexMapToROS(sensor_msgs::ImagePtr body_index_map_image, k4a::image& k4a_body_index_map, const k4abt::frame& body_frame);
6872
#endif
6973

7074
private:
@@ -111,6 +115,8 @@ class K4AROSDevice
111115

112116
#if defined(K4A_BODY_TRACKING)
113117
ros::Publisher body_marker_publisher_;
118+
119+
image_transport::Publisher body_index_map_publisher_;
114120
#endif
115121

116122
// Parameters

include/azure_kinect_ros_driver/k4a_ros_types.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,26 @@ struct BgraPixel
1515
uint8_t Alpha;
1616
};
1717

18+
#if defined(K4A_BODY_TRACKING)
19+
using BodyIndexMapPixel = uint8_t;
20+
21+
struct Color
22+
{
23+
float r, g, b, a;
24+
};
25+
26+
using ColorPalette = std::array<Color, 8>;
27+
// a palette of 8 colors to colorize the different body markers and the body index map
28+
static const ColorPalette BODY_COLOR_PALETTE{{
29+
{1.0f, 0.0f, 0.0f, 1.0f},
30+
{0.0f, 1.0f, 0.0f, 1.0f},
31+
{0.0f, 0.0f, 1.0f, 1.0f},
32+
{1.0f, 1.0f, 0.0f, 1.0f},
33+
{1.0f, 0.0f, 1.0f, 1.0f},
34+
{0.0f, 1.0f, 1.0f, 1.0f},
35+
{0.0f, 0.0f, 0.0f, 1.0f},
36+
{1.0f, 1.0f, 1.0f, 1.0f}
37+
}};
38+
#endif
39+
1840
#endif // K4A_ROS_TYPES_H

src/k4a_ros_device.cpp

Lines changed: 86 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,8 @@ K4AROSDevice::K4AROSDevice(const NodeHandle &n, const NodeHandle &p) : k4a_devic
226226

227227
#if defined(K4A_BODY_TRACKING)
228228
body_marker_publisher_ = node_.advertise<MarkerArray>("body_tracking_data", 1);
229+
230+
body_index_map_publisher_ = image_transport_.advertise("body_index_map/image_raw", 1);
229231
#endif
230232
}
231233

@@ -781,10 +783,12 @@ k4a_result_t K4AROSDevice::getBodyMarker(const k4abt_body_t& body, MarkerPtr mar
781783
marker_msg->id = body.id * 100 + jointType;
782784
marker_msg->type = Marker::SPHERE;
783785

784-
marker_msg->color.a = 1.0;
785-
marker_msg->color.r = 255;
786-
marker_msg->color.g = 0;
787-
marker_msg->color.b = 0;
786+
Color color = BODY_COLOR_PALETTE[body.id % BODY_COLOR_PALETTE.size()];
787+
788+
marker_msg->color.a = color.a;
789+
marker_msg->color.r = color.r;
790+
marker_msg->color.g = color.g;
791+
marker_msg->color.b = color.b;
788792

789793
marker_msg->scale.x = 0.05;
790794
marker_msg->scale.y = 0.05;
@@ -800,6 +804,56 @@ k4a_result_t K4AROSDevice::getBodyMarker(const k4abt_body_t& body, MarkerPtr mar
800804

801805
return K4A_RESULT_SUCCEEDED;
802806
}
807+
808+
k4a_result_t K4AROSDevice::getBodyIndexMap(const k4abt::frame& body_frame, sensor_msgs::ImagePtr body_index_map_image)
809+
{
810+
k4a::image k4a_body_index_map = body_frame.get_body_index_map();
811+
812+
if (!k4a_body_index_map)
813+
{
814+
ROS_ERROR("Cannot render body index map: no body index map");
815+
return K4A_RESULT_FAILED;
816+
}
817+
818+
return renderBodyIndexMapToROS(body_index_map_image, k4a_body_index_map, body_frame);
819+
}
820+
821+
k4a_result_t K4AROSDevice::renderBodyIndexMapToROS(sensor_msgs::ImagePtr body_index_map_image, k4a::image& k4a_body_index_map, const k4abt::frame& body_frame)
822+
{
823+
// Access the body index map as an array of uint8 pixels
824+
BodyIndexMapPixel* body_index_map_frame_buffer = k4a_body_index_map.get_buffer();
825+
auto body_index_map_pixel_count = k4a_body_index_map.get_size() / sizeof(BodyIndexMapPixel);
826+
827+
// Build the ROS message
828+
body_index_map_image->height = k4a_body_index_map.get_height_pixels();
829+
body_index_map_image->width = k4a_body_index_map.get_width_pixels();
830+
body_index_map_image->encoding = sensor_msgs::image_encodings::MONO8;
831+
body_index_map_image->is_bigendian = false;
832+
body_index_map_image->step = k4a_body_index_map.get_width_pixels() * sizeof(BodyIndexMapPixel);
833+
834+
// Enlarge the data buffer in the ROS message to hold the frame
835+
body_index_map_image->data.resize(body_index_map_image->height * body_index_map_image->step);
836+
837+
// If the pixel doesn't belong to a detected body the pixels value will be 255 (K4ABT_BODY_INDEX_MAP_BACKGROUND).
838+
// If the pixel belongs to a detected body the value is calculated by body id mod 255.
839+
// This means that up to body id 254 the value is equals the body id.
840+
// Afterwards it will lose the relation to the body id and is only a information for the segmentation of the image.
841+
for (size_t i = 0; i < body_index_map_pixel_count; ++i)
842+
{
843+
BodyIndexMapPixel val = body_index_map_frame_buffer[i];
844+
if (val == K4ABT_BODY_INDEX_MAP_BACKGROUND)
845+
{
846+
body_index_map_image->data[i] = K4ABT_BODY_INDEX_MAP_BACKGROUND;
847+
}
848+
else
849+
{
850+
auto body_id = k4abt_frame_get_body_id(body_frame.handle(), val);
851+
body_index_map_image->data[i] = body_id % K4ABT_BODY_INDEX_MAP_BACKGROUND;
852+
}
853+
}
854+
855+
return K4A_RESULT_SUCCEEDED;
856+
}
803857
#endif
804858

805859
void K4AROSDevice::framePublisherThread()
@@ -962,7 +1016,7 @@ void K4AROSDevice::framePublisherThread()
9621016

9631017
#if defined(K4A_BODY_TRACKING)
9641018
// Publish body markers when body tracking is enabled and a depth image is available
965-
if (params_.body_tracking_enabled && body_marker_publisher_.getNumSubscribers() > 0)
1019+
if (params_.body_tracking_enabled && (body_marker_publisher_.getNumSubscribers() > 0 || body_index_map_publisher_.getNumSubscribers() > 0))
9661020
{
9671021
capture_time = timestampToROS(capture.get_depth_image().get_device_timestamp());
9681022

@@ -983,23 +1037,45 @@ void K4AROSDevice::framePublisherThread()
9831037
}
9841038
else
9851039
{
986-
auto num_bodies = body_frame.get_num_bodies();
987-
if (num_bodies > 0)
1040+
if (body_marker_publisher_.getNumSubscribers() > 0)
9881041
{
1042+
// Joint marker array
9891043
MarkerArrayPtr markerArrayPtr(new MarkerArray);
1044+
auto num_bodies = body_frame.get_num_bodies();
9901045
for (size_t i = 0; i < num_bodies; ++i)
9911046
{
992-
k4abt_body_t body = body_frame.get_body(i);
993-
for (int j = 0; j < (int) K4ABT_JOINT_COUNT; ++j)
1047+
k4abt_body_t body = body_frame.get_body(i);
1048+
for (int j = 0; j < (int)K4ABT_JOINT_COUNT; ++j)
9941049
{
9951050
MarkerPtr markerPtr(new Marker);
9961051
getBodyMarker(body, markerPtr, j, capture_time);
9971052
markerArrayPtr->markers.push_back(*markerPtr);
9981053
}
9991054
}
1000-
10011055
body_marker_publisher_.publish(markerArrayPtr);
10021056
}
1057+
1058+
if (body_index_map_publisher_.getNumSubscribers() > 0)
1059+
{
1060+
// Body index map
1061+
ImagePtr body_index_map_frame(new Image);
1062+
result = getBodyIndexMap(body_frame, body_index_map_frame);
1063+
1064+
if (result != K4A_RESULT_SUCCEEDED)
1065+
{
1066+
ROS_ERROR_STREAM("Failed to get body index map");
1067+
ros::shutdown();
1068+
return;
1069+
}
1070+
else if (result == K4A_RESULT_SUCCEEDED)
1071+
{
1072+
// Re-sychronize the timestamps with the capture timestamp
1073+
body_index_map_frame->header.stamp = capture_time;
1074+
body_index_map_frame->header.frame_id = calibration_data_.tf_prefix_ + calibration_data_.depth_camera_frame_;
1075+
1076+
body_index_map_publisher_.publish(body_index_map_frame);
1077+
}
1078+
}
10031079
}
10041080
}
10051081
}

0 commit comments

Comments
 (0)