8 sensor_msgs::msg::PointCloud2
create_colored_pointcloud(
const std::shared_ptr<rtabmap::SensorData> & sensor_data,
const std_msgs::msg::Header & header)
11 image_geometry::PinholeCameraModel model;
12 sensor_msgs::msg::CameraInfo info_msg;
13 rtabmap_conversions::cameraModelToROS(sensor_data->cameraModels()[0], info_msg);
14 model.fromCameraInfo(info_msg);
16 auto cloud_msg = std::make_shared<sensor_msgs::msg::PointCloud2>();
17 cloud_msg->header = header;
18 cloud_msg->height = sensor_data->depthRaw().rows;
19 cloud_msg->width = sensor_data->depthRaw().cols;
20 cloud_msg->is_dense =
false;
21 cloud_msg->is_bigendian =
false;
23 if (sensor_data->depthRaw().cols != sensor_data->imageRaw().cols || sensor_data->depthRaw().rows != sensor_data->imageRaw().rows) {
25 rclcpp::get_logger(
"cslam"),
26 "Depth image size (%dx%d) doesn't match RGB image size (%dx%d)!",
27 sensor_data->depthRaw().cols, sensor_data->depthRaw().rows, sensor_data->imageRaw().cols, sensor_data->imageRaw().rows);
28 cloud_msg->height = 0;
33 sensor_msgs::PointCloud2Modifier pcd_modifier(*cloud_msg);
34 pcd_modifier.setPointCloud2FieldsByString(2,
"xyz",
"rgb");
37 if (sensor_data->depthRaw().type() == CV_16UC1) {
38 depth_image_to_pointcloud<uint16_t>(sensor_data, cloud_msg, model);
39 }
else if (sensor_data->depthRaw().type() == CV_32FC1) {
40 depth_image_to_pointcloud<float>(sensor_data, cloud_msg, model);
47 if (sensor_data->imageRaw().type() == CV_8UC3) {
49 }
else if (sensor_data->imageRaw().type() == CV_8UC1) {
61 const std::shared_ptr<rtabmap::SensorData> & sensor_data,
62 sensor_msgs::msg::PointCloud2::SharedPtr & cloud_msg,
63 const image_geometry::PinholeCameraModel & model,
67 float center_x = model.cx();
68 float center_y = model.cy();
72 float constant_x = unit_scaling / model.fx();
73 float constant_y = unit_scaling / model.fy();
74 float bad_point = std::numeric_limits<float>::quiet_NaN();
76 sensor_msgs::PointCloud2Iterator<float> iter_x(*cloud_msg,
"x");
77 sensor_msgs::PointCloud2Iterator<float> iter_y(*cloud_msg,
"y");
78 sensor_msgs::PointCloud2Iterator<float> iter_z(*cloud_msg,
"z");
79 const T * depth_row =
reinterpret_cast<const T *
>(&sensor_data->depthRaw().data[0]);
80 int row_step = sensor_data->depthRaw().step /
sizeof(T);
81 for (
int v = 0; v < static_cast<int>(cloud_msg->height); ++v, depth_row += row_step) {
82 for (
int u = 0; u < static_cast<int>(cloud_msg->width); ++u, ++iter_x, ++iter_y, ++iter_z) {
83 T depth = depth_row[u];
87 if (range_max != 0.0) {
90 *iter_x = *iter_y = *iter_z = bad_point;
96 *iter_x = (u - center_x) * depth * constant_x;
97 *iter_y = (v - center_y) * depth * constant_y;
104 const std::shared_ptr<rtabmap::SensorData> & sensor_data,
105 sensor_msgs::msg::PointCloud2::SharedPtr & cloud_msg)
108 int red_offset, green_offset, blue_offset, color_step;
109 if (sensor_data->imageRaw().type() == CV_8UC3) {
114 }
else if (sensor_data->imageRaw().type() == CV_8UC1) {
123 sensor_msgs::PointCloud2Iterator<uint8_t> iter_r(*cloud_msg,
"r");
124 sensor_msgs::PointCloud2Iterator<uint8_t> iter_g(*cloud_msg,
"g");
125 sensor_msgs::PointCloud2Iterator<uint8_t> iter_b(*cloud_msg,
"b");
126 const uint8_t * rgb = &sensor_data->imageRaw().data[0];
127 int rgb_skip = sensor_data->imageRaw().step - sensor_data->imageRaw().cols * color_step;
128 for (
int v = 0; v < static_cast<int>(cloud_msg->height); ++v, rgb += rgb_skip) {
129 for (
int u = 0; u < static_cast<int>(cloud_msg->width); ++u,
130 rgb += color_step, ++iter_r, ++iter_g, ++iter_b)
132 *iter_r = rgb[red_offset];
133 *iter_g = rgb[green_offset];
134 *iter_b = rgb[blue_offset];
void depth_image_to_pointcloud(const std::shared_ptr< rtabmap::SensorData > &sensor_data, sensor_msgs::msg::PointCloud2::SharedPtr &cloud_msg, const image_geometry::PinholeCameraModel &model, double range_max=0.0)
Convert depth image to pointcloud.
sensor_msgs::msg::PointCloud2 create_colored_pointcloud(const std::shared_ptr< rtabmap::SensorData > &sensor_data, const std_msgs::msg::Header &header)
Create a colored pointcloud message.
void add_rgb_to_pointcloud(const std::shared_ptr< rtabmap::SensorData > &sensor_data, sensor_msgs::msg::PointCloud2::SharedPtr &cloud_msg)
Add color to pointcloud.