davidcaron / pclpy

Python bindings for the Point Cloud Library (PCL)
MIT License
426 stars 59 forks source link
computer-vision lidar pcl point-cloud python

pclpy: PCL for python

conda Python version conda PCL version

.github/workflows/ci.yml

Python bindings for the Point Cloud Library (PCL). Generated from headers using CppHeaderParser and pybind11.

Install using conda: conda install -c conda-forge -c davidcaron pclpy (see Installation below)

Contributions, issues, comments are welcome!

Github repository: https://www.github.com/davidcaron/pclpy

Motivation

Many other python libraries tried to bind PCL. The most popular one being python-pcl, which uses Cython. While Cython is really powerful, binding C++ templates isn't one of its strenghts (and PCL uses templates heavily). The result for python-pcl is a lot of code repetition, which is hard to maintain and to add features to, and incomplete bindings of PCL's classes and point types.

Using pybind11, we use C++ directly. Templates, boost::smart_ptr and the buffer protocol are examples of things that are simpler to implement.

The results so far are very promising. A large percentage of PCL is covered.

Installation

We use conda to release pclpy. To install, use this command:

conda install -c conda-forge -c davidcaron pclpy

Don't forget to add both channels, or else conda won't be able to find all dependencies.

Windows: python 3.6 and 3.7 are supported

Linux: python 3.6, 3.7 and 3.8 are supported

Features

Example

You can use either a high level, more pythonic api, or the wrapper over the PCL api. The wrapper is meant to be as close as possible to the original PCL C++ api.

Here is how you would use the library to process Moving Least Squares. See the PCL documentation: http://pointclouds.org/documentation/tutorials/resampling.php

Using the higher level api:

import pclpy

# read a las file
point_cloud = pclpy.read("street.las", "PointXYZRGBA")
# compute mls
output = point_cloud.moving_least_squares(search_radius=0.05, compute_normals=True, num_threads=8)

Or the wrapper over the PCL api:

import pclpy
from pclpy import pcl

point_cloud = pclpy.read("street.las", "PointXYZRGBA")
mls = pcl.surface.MovingLeastSquaresOMP.PointXYZRGBA_PointNormal()
tree = pcl.search.KdTree.PointXYZRGBA()
mls.setSearchRadius(0.05)
mls.setPolynomialFit(False)
mls.setNumberOfThreads(12)
mls.setInputCloud(point_cloud)
mls.setSearchMethod(tree)
mls.setComputeNormals(True)
output = pcl.PointCloud.PointNormal()
mls.process(output)

You can see the wrapper is very close to the C++ version:

// C++ version

pcl::PointCloud<pcl::PointXYZ>::Ptr point_cloud (new pcl::PointCloud<pcl::PointXYZ> ());
pcl::io::loadPCDFile ("bunny.pcd", *point_cloud);
pcl::MovingLeastSquaresOMP<pcl::PointXYZ, pcl::PointNormal> mls;
pcl::search::KdTree<pcl::PointXYZ>::Ptr tree (new pcl::search::KdTree<pcl::PointXYZ>);
mls.setSearchRadius (0.05);
mls.setPolynomialFit (false);
mls.setNumberOfThreads (12);
mls.setInputCloud (point_cloud);
mls.setSearchMethod (tree);
mls.setComputeNormals (true);
pcl::PointCloud<pcl::PointNormal> output;
mls.process (output);

Modules

Not Implemented

(see github issues and the what to skip section in generators/config.py)

Building

Build scripts are in the scripts folder.

  1. Create your conda environment: conda env create -n pclpy -f environment.yml

  2. Activate your environment: conda activate pclpy

  3. Install development dependencies: pip install -r requirements-dev.txt

  4. Download a copy of PCL Windows: powershell scripts\download_pcl.ps1 Linux: scripts\download_pcl.sh

  5. Generate pybind11 bindings Windows: powershell scripts\generate_points_and_bindings.ps1 Linux: scripts\generate_points_and_bindings.sh

  6. For development, build inplace using python python setup.py build_ext -i

    For a release, use the scripts/conda_build.bat (or conda_build.sh) script

On Windows, these setup.py arguments can cpeed up the build:

Roadmap