21 #define NODE_CLASS_NAME TexturePointCloudNode
22 #define NODE_NAME "texture_point_cloud"
35 sensor_msgs::msg::ImageConstPtr latestImage;
36 std::shared_ptr<ensenso::pcl::PointCloud> latestPointCloud;
46 pointCloudSubscription = ensenso::pcl::create_subscription<ensenso::pcl::PointCloud>(
47 nh,
"point_cloud", 10, &NODE_CLASS_NAME::onPointCloudReceived,
this);
49 texturedPointCloudPublisher =
50 ensenso::pcl::create_publisher<ensenso::pcl::PointCloudColored>(nh,
"textured_point_cloud", 1);
52 latestPointCloud = std::make_shared<ensenso::pcl::PointCloud>();
56 void onImageReceived(sensor_msgs::msg::ImageConstPtr
const& image)
58 std::lock_guard<std::mutex> lock(mutex);
65 std::lock_guard<std::mutex> lock(mutex);
74 if (!latestImage.get() || !latestPointCloud.get())
89 auto texturedPointCloud = texturePointCloudFromRectifiedImage(image->image);
94 std::unique_ptr<ensenso::pcl::PointCloudColored> texturePointCloudFromRectifiedImage(cv::Mat
const& image)
96 auto texturedPointCloud = ensenso::std::make_unique<ensenso::pcl::PointCloudColored>();
98 if (
static_cast<int>(latestPointCloud->width) != image.cols ||
99 static_cast<int>(latestPointCloud->height) != image.rows)
101 ENSENSO_ERROR(nh,
"The point cloud does not have the same format as the rectified image!");
102 return texturedPointCloud;
105 texturedPointCloud->header.frame_id = latestPointCloud->header.frame_id;
106 texturedPointCloud->header.stamp = latestPointCloud->header.stamp;
108 texturedPointCloud->is_dense = latestPointCloud->is_dense;
109 texturedPointCloud->width = latestPointCloud->width;
110 texturedPointCloud->height = latestPointCloud->height;
111 texturedPointCloud->points.resize(texturedPointCloud->width * texturedPointCloud->height);
113 for (
size_t x = 0; x < latestPointCloud->width; x++)
115 for (
size_t y = 0; y < latestPointCloud->height; y++)
117 auto& point = texturedPointCloud->at(x, y);
119 point.x = latestPointCloud->at(x, y).x;
120 point.y = latestPointCloud->at(x, y).y;
121 point.z = latestPointCloud->at(x, y).z;
123 if (image.channels() == 3)
125 cv::Vec3b color = image.at<cv::Vec3b>(y, x);
126 point.b = color.val[0];
127 point.g = color.val[1];
128 point.r = color.val[2];
132 uchar color = image.at<uchar>(y, x);
140 return texturedPointCloud;
144 int main(
int argc,
char** argv)