Files
rtabmap_ros/rtabmap_util/doc/point_cloud_xyz.md
T
matlabbe 61edb4ee85 rtabmap_util tests and doc (#1450)
* Initial tests

* more tests

* More in-depth deskew() testing

* slightly less verbose clamping corruption warning

* added tf buffer related tests

* added remaining tests

* Added rosdoc2, improve tests when we require sync of odom stamp and sensor stamp

* cleanup doc

* fixing ci

* rtabmap_util tests and doc

* Added db_player tests

* Added MapsManager tests

* Added map_assembler tests

* Documenting node first draft

* relative links

* Fixed british->usa english style. Reviewed all md files.

* added link to install ros1

* updated badges

* added Iron

* added ubuntu

* added codecov

* updated coverage ci

* fixing rosdep

* updated ci cov job

* ci bump

* fixing cov ci

* small doc cleanup
2026-09-07 21:23:22 -07:00

5.4 KiB

point_cloud_xyz

Projects a depth or disparity image into a point cloud.

The node takes a depth image and its calibration and produces a sensor_msgs/msg/PointCloud2, with optional decimation, range limits, voxel and radius filtering, and normal estimation — the same preprocessing RTAB-Map would do internally, done once and shared.

depth_image_proc's own point_cloud_xyz does the bare projection; this node exists for the filtering, and for accepting disparity directly.

See point_cloud_xyzrgb for the colored equivalent.

Usage

ros2 run rtabmap_util point_cloud_xyz --ros-args \
  -r depth/image:=/camera/depth/image_raw \
  -r depth/camera_info:=/camera/depth/camera_info \
  -p decimation:=4 -p max_depth:=5.0 -p voxel_size:=0.05
ComposableNode(
    package='rtabmap_util',
    plugin='rtabmap_util::PointCloudXYZ',
    name='point_cloud_xyz',
    parameters=[{'decimation': 4, 'max_depth': 5.0, 'voxel_size': 0.05}],
    remappings=[('depth/image', '/camera/depth/image_raw'),
                ('depth/camera_info', '/camera/depth/camera_info')])

Subscribed Topics

The node listens on two independent input sets and uses whichever one is being published. Only one of them should be connected.

Depth

Topic Type Description
depth/image sensor_msgs/msg/Image 32FC1 (meters), 16UC1 (millimeters) or mono16. Goes through image_transport, see depth_transport parameter below.
depth/camera_info sensor_msgs/msg/CameraInfo

Disparity

Topic Type Description
disparity/image stereo_msgs/msg/DisparityImage 32FC1 or 16SC1. The 16-bit form is fixed point, 16 units per pixel of disparity.
disparity/camera_info sensor_msgs/msg/CameraInfo

Published Topics

Topic Type Description
cloud sensor_msgs/msg/PointCloud2 In the frame of the input image, stamped with it. Carries normal_* fields when normals are enabled.

Nothing is computed unless cloud has a subscriber.

Parameters

Synchronization

Parameter Type Default Description
approx_sync bool true Match image and camera info by nearest stamp. Set false when they are published with identical stamps, which is stricter and cheaper.
approx_sync_max_interval double 0.0 With approx_sync, reject pairs further apart than this many seconds. 0 disables the check.
topic_queue_size int 1 Queue depth of each input subscription.
sync_queue_size int 10 Queue depth of the synchronizer.
qos int 0 Reliability of the image and disparity subscriptions: 0 system default, 1 reliable, 2 best effort.
qos_camera_info int value of qos Reliability of the camera info subscriptions.
depth_transport string "raw" image_transport plugin for depth/image, e.g. compressedDepth.

Projection and filtering, applied in this order

Parameter Type Default Description
decimation int 1 Keep one pixel in decimation, in each direction. 2 gives a quarter of the points. The image dimensions must divide by it.
roi_ratios string "" Crop before projecting, as four ratios "left right top bottom", e.g. "0.1 0.1 0 0.2".
min_depth double 0.0 Discard points nearer than this, in meters. 0 disables.
max_depth double 0.0 Discard points further than this, in meters. 0 disables.
voxel_size double 0.0 Downsample to one point per voxel of this size, in meters. 0 disables.
noise_filter_radius double 0.0 Radius outlier removal, in meters. 0 disables.
noise_filter_min_neighbors int 5 Neighbors a point needs within noise_filter_radius to survive.
normal_k int 0 Estimate normals from this many nearest neighbors. 0 disables.
normal_radius double 0.0 Estimate normals from all neighbors within this radius, in meters. 0 disables.
filter_nans bool false See Organized output.

Organized output

By default the cloud stays organized: one point per pixel, in image order, with out-of-range points set to NaN rather than removed. That layout is what lets consumers treat the cloud as an image, and it is why a cloud with max_depth set still reports the full point count.

Set filter_nans to true to drop the invalid points instead. The cloud becomes unorganized and its size reflects what is actually in range — including being empty when nothing is.

Voxel and radius filtering also produce unorganized clouds, since both remove points.

Notes

decimation is by far the cheapest way to cut the cost of everything downstream, and on a depth image it loses very little: neighboring pixels of a surface are nearly redundant. Reach for it before voxel_size.