ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question

sensor_msgs::PointCloud2 remove field from point cloud

asked 2022-08-18 09:38:02 -0600

labude gravatar image

updated 2022-08-19 10:28:22 -0600

I have a sensor_msg::PointCloud2 with the following fields/channels: x, y, z, intensity, ring, time. However, I need a copy of this cloud containing only the x, y, z data.

Erasing the fields from the sensor_msgs::PointField does not suffice, as far as I understood these are only the "labels" for the data and erasing them won't change the size of the point cloud. Thus, I need to erase the data points themselves.

What would be the best way to achieve this? Is there even a function like pcl::removeField() that I failed to see?

edit retag flag offensive close merge delete

2 Answers

Sort by ยป oldest newest most voted

answered 2022-08-19 10:50:19 -0600

labude gravatar image

In case someone finds this useful, here is how I solved it:

Convert the sensor msg to a PointCloud<pointxyz>, this removes all fields except xyz, then convert back to a sensor msg.

An example:

  sensor_msgs::PointCloud2 msg; // contains x,y,z and other fields such as intensity
  pcl::PointCloud<pcl::PointXYZ> tmp;
  pcl::fromROSMsg( msg, tmp );
  // Here you could perform operations on the point cloud
  pcl::toROSMsg( tmp, msg );
edit flag offensive delete link more

answered 2022-08-18 16:51:17 -0600

Mike Scheutzow gravatar image

The simplest method is to create a new point cloud and create new points having only the data you want.

edit flag offensive delete link more


Would it be possible for you to give a short example? I am not sure about how to extract the desired data from the point cloud. My attempt looks like this: At first I copy the header and (only) the needed fields from the original message (input) to a new one (copy). Then I try to copy the data:

      for ( sensor_msgs::PointCloud2ConstIterator<float> data_it( input, "x" ); data_it != data_it.end(); ++data_it )
    // x is at position [0], followed by y, z data_it[0] ); data_it[1] ); data_it[2] );

This doesn't work, however, the data of the copy remain empty.

labude gravatar image labude  ( 2022-08-19 07:22:49 -0600 )edit

Have you read this:

Hint: a message is not a pcl::PointCloud object.

Mike Scheutzow gravatar image Mike Scheutzow  ( 2022-08-19 08:44:59 -0600 )edit

You are right, I mixed up the different data types.

For my purposes I found this solution: Convert the sensor_msgs::PointCloud2 to a pcl::PointCloud<pcl::pointxyz> using pcl::fromROSMsg( msg, pcl_xyz ). By doing so all other fields are dropped, only x,y,z remains.

Then you can perform some operations on the point cloud and finally convert it back to a sensor_msgs::PointCloud2 pcl::toROSMsg(pcl_xyz, msg_xyz );

This may not be the fastest solution but it works.

labude gravatar image labude  ( 2022-08-19 10:35:02 -0600 )edit

Question Tools

1 follower


Asked: 2022-08-18 09:38:02 -0600

Seen: 465 times

Last updated: Aug 19 '22