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)
CvImageConstPtr toCvShare(const sensor_msgs::ImageConstPtr &source, const std::string &encoding=std::string())
#define POINT_CLOUD_SUBSCRIPTION_CALLBACK(callback, T, arg_name)
#define SINGLE_NODE_WRAPPER(ClassName, NodeName)
void ENSENSO_ERROR(T... args)
inline ::image_transport::Subscriber create_subscription(ensenso::ros::NodeHandle &nh, ::std::string const &topic_name, void(T::*callback)(sensor_msgs::msg::ImageConstPtr const &), T *object)
ensenso::ros::Publisher< T > PointCloudPublisher
int main(int argc, char **argv)
void publishPointCloud(ensenso::ros::Publisher< T > const &publisher, std::unique_ptr< T > pointCloud)
#define SINGLE_NODE_CTOR(ClassName, NodeName)
#define CREATE_NODE_HANDLE(nh)
SINGLE_NODE_CLASS(NODE_CLASS_NAME)
::ros::NodeHandle NodeHandle
#define STORE_POINT_CLOUD(point_cloud_boost_ptr, point_cloud_std_ptr)
::pcl::PointCloud<::pcl::PointXYZ > PointCloud