Welcome to pointcloudset’s documentation!
Features
Handles point clouds over time
Directly read ROS files and many pointcloud file formats.
Generate a dataset from multiple pointclouds. For example from thousands of .las files.
Building complex pipelines with a clean and maintainable code
newpointcloud = pointcloud.limit("x",-5,5).filter("quantile","reflectivity", ">",0.5)
Apply arbitrary functions to datasets of point clouds
def isolate_target(frame: PointCloud) -> PointCloud:
return frame.limit("x",0,1).limit("y",0,1)
def diff_to_pointcloud(pointcloud: PointCloud, to_compare: PointCloud) -> PointCloud:
return pointcloud.diff("pointcloud", to_compare)
result = dataset.apply(isolate_target).apply(diff_to_pointcloud, to_compare=dataset[0])
Includes powerful aggregation method agg similar to pandas
dataset.agg(["min","max","mean","std"])
Support for large files with lazy evaluation and parallel processing
Support for numerical data per point (intensity, range, noise …)
Interactive 3D visualisation
High level processing based on dask, pandas, scipy, scikit-learn
Docker image is available
Optimised - but not limited to - automotive lidar
A command line tool to convert ROS 1 & 2 files
Use case examples
Post processing and analytics of a lidar dataset recorded by ROS
A collection of multiple lidar scans from a terrestrial laser scanner
Comparison of multiple point clouds to a ground truth
Analytics of point clouds over time
Developing algorithms on a single frame and then applying them to huge datasets
Installation with pip
Install python package with pip:
pip install pointcloudset
Optional extras
For faster clustering on large point clouds, install the optional numba extra to enable JIT-accelerated union-find in PointCloud.get_cluster():
pip install pointcloudset[numba]
Without this extra, a pure-Python fallback is used automatically with no change in behaviour.
Installation with Docker
The easiest way to get started is to use the pre-build docker tgoelles/pointcloudset.
Quickstart
Reading ROS1 or ROS2 files:
import pointcloudset as pcs
from pathlib import Path
import urllib.request
urllib.request.urlretrieve(
"https://github.com/virtual-vehicle/pointcloudset/raw/master/tests/testdata/test.bag", "test.bag"
)
dataset = pcs.Dataset.from_file(Path("test.bag"), topic="/os1_cloud_node/points", keep_zeros=False)
pointcloud = dataset[1]
pointcloud.plot("x", hover_data=True)
You can also generate a dataset from multiple pointclouds from formats like las, pcd, csv, and xyz.
PointCloud.to_file(...) currently writes csv, xyz, las, and pcd.
For text formats, csv defaults to writing a header and also supports header=False;
xyz defaults to headerless output and also supports header=True.
When reading files, PointCloud.from_file(...) supports normalize_xyz (default False).
If a file uses uppercase coordinate headers X, Y, Z, reading fails unless you pass normalize_xyz=True.
This makes the conversion explicit while keeping internal processing consistent with lowercase x, y, z.
import pointcloudset as pcs
from pathlib import Path
import urllib.request
urllib.request.urlretrieve(
"https://github.com/virtual-vehicle/pointcloudset/raw/master/tests/testdata/las_files/test_tree.las",
"test_tree.las",
)
urllib.request.urlretrieve(
"https://github.com/virtual-vehicle/pointcloudset/raw/master/tests/testdata/pcd_files/test_tree.pcd",
"test_tree.pcd",
)
las_pc = pcs.PointCloud.from_file(Path("test_tree.las"), normalize_xyz=True)
pcd_pc = pcs.PointCloud.from_file(Path("test_tree.pcd"))
dataset = pcs.Dataset.from_instance("pointclouds", [las_pc, pcd_pc])
pointcloud = dataset[1]
pointcloud.plot("z", hover_data=True)
Read the html documentation.
Have a look at the tutorial notebooks in the documentation folder
For even more usage examples you can have a look at the tests
CLI to convert ROS1 and ROS2 files: pointcloudset convert
The package includes a CLI to convert pointclouds in ROS1 and ROS2 files into pointcloudset directories or native file formats.
It currently writes csv, xyz, las, and pcd files and handles both mcap and db3 ROS2 inputs.
pointcloudset convert test.bag --output-format las --output-dir converted_las
You can view PointCloud2 messages with
pointcloudset topics test.bag
Tipp: If you have uv installed you can simply run:
uvx pointcloudset --help
Citation and contact
Thomas Gölles
email: thomas.goelles@v2c2.at
Please cite our JOSS paper if you use pointcloudset.
@article{Goelles2021,
doi = {10.21105/joss.03471},
url = {https://doi.org/10.21105/joss.03471},
year = {2021},
publisher = {The Open Journal},
volume = {6},
number = {65},
pages = {3471},
author = {Thomas Goelles and Birgit Schlager and Stefan Muckenhuber and Sarah Haas and Tobias Hammer},
title = {`pointcloudset`: Efficient Analysis of Large Datasets of Point Clouds Recorded Over Time},
journal = {Journal of Open Source Software}
}
Tutorial
Convert ROS 1 and ROS 2 files
Contribute
Python API
- How to read the API documentation
- pointcloudset package
- pointcloudset.cluster package
- pointcloudset.diff package
- pointcloudset.filter package
- pointcloudset.geometry package
- pointcloudset.io package
- pointcloudset.pipeline package
- pointcloudset.plot package
- pointcloudset.dataset module
- pointcloudset.dataset_core module
- pointcloudset.pointcloud module
- pointcloudset.pointcloud_core module
Changelog
- Changelog
- Unreleased
- 0.14.0 - (2026-05-11)
- 0.13.0 - (2026-05-05)
- 0.12.1 - (2026-05-04)
- 0.12.0 - (2026-05-05)
- 0.11.0- (2025-05-22)
- 0.10.1- (2025-04-28)
- 0.10.0 - (2024-12-03)
- 0.9.0 - (2023-03-30)
- 0.8.1 - (2023-03-23)
- 0.8.0 - (2022-11-13)
- 0.7.0 - (2022-09-27)
- 0.6.3 - (2022-06-08)
- 0.6.2 - (2022-06-03)
- 0.6.1 - (2022-06-03)
- 0.6.0 - (2022-06-03)
- 0.5.1 - (2022-05-30)
- 0.5.0 - (2022-05-30)
- 0.4.3 - (2022-05-10)
- 0.4.2 - (2022-05-10)
- 0.4.1 - (2022-02-22)
- 0.4.0 - (2022-02-22)
- 0.3.4 - (2022-02-18)
- 0.3.3 - (2021-09-27)
- 0.3.2 - (2021-08-18)
- 0.3.1 - (2021-08-17)
- 0.3.0 (2021-08-17)
- 0.2.3 (2021-07-12)