API Reference

This is the auto-generated API reference for the libtts library.

Ground Detection Functions

Ground Detection

Functions for detecting ground points and classifying points (ground and vegetation).

Current implementation: creating a Digital Terrain Model (DTM), and classifying points as ground or vegetation based on the height.

Example

out_gd_file, out_veg_file = libtts.run_ground_detection(infile = infile, out_gd_file = out_gd_file, out_veg_file = out_veg_file, grid_size=0.1, height_threshold = 0.5)

libtts.ground_detection.calculate_height_above_ground(points: ndarray, ground_grid_x: ndarray, ground_grid_y: ndarray, ground_grid_z: ndarray) ndarray[source]

Calculates the vertical distance of each point from a pre-computed ground grid.

Parameters:
  • points (np.ndarray) – Nx3 array of (x, y, z) points to normalize.

  • ground_grid_x (np.ndarray) – 2D array of X coordinates for the ground model.

  • ground_grid_y (np.ndarray) – 2D array of Y coordinates for the ground model.

  • ground_grid_z (np.ndarray) – 2D array of Z values for the ground model.

Returns:

An Nx4 array of the original points with an added height column (x, y, z, h).

Return type:

np.ndarray

libtts.ground_detection.classify_ground_and_vegetation(points: ndarray, height_threshold: float = 0.5, out_gd_file: str = None, out_veg_file: str = None, **ground_detection_params) tuple[ndarray, ndarray][source]

Performs the full workflow: detect ground, normalize heights, and classify.

Parameters:
  • points (np.ndarray) – The input Nx3 point cloud.

  • height_threshold (float) – Height to separate vegetation from ground.

  • out_gd_file (str, optional) – Path to save the ground points.

  • out_veg_file (str, optional) – Path to save the vegetation points.

  • **ground_detection_params – Keyword arguments passed to detect_ground(), e.g., grid_size=0.5.

Returns:

A tuple containing two numpy arrays:

  • The first element contains the points classified as ground (Nx3).

  • The second element contains the points classified as vegetation (Mx3).

Return type:

tuple[np.ndarray, np.ndarray]

libtts.ground_detection.detect_ground(points: ndarray, grid_size: float = 0.5, outlier_std_dev: float = 1.0, gaussian_kernel_size: int = 5) tuple[ndarray, ndarray, ndarray, ndarray][source]

Detects the ground surface and returns it as both a point cloud and a grid.

Parameters:
  • points (np.ndarray) – The input Nx3 point cloud.

  • grid_size (float) – The resolution for the intermediate ground grid.

  • outlier_std_dev (float) – Std deviations for outlier removal.

  • gaussian_kernel_size (int) – Kernel size for smoothing.

Returns:

A tuple containing:

  • ground_model_points (np.ndarray): Mx3 array of the final ground grid points.

  • grid_x (np.ndarray): 2D array of X coordinates for the grid.

  • grid_y (np.ndarray): 2D array of Y coordinates for the grid.

  • grid_z (np.ndarray): 2D array of Z values for the grid.

Return type:

tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray]

libtts.ground_detection.plot_ground_model(grid_x: ndarray, grid_y: ndarray, grid_z: ndarray, title: str = 'Ground Model (2D Heatmap)')[source]

Creates a 2D heatmap directly from the generated ground grid.

Parameters:
  • grid_x (np.ndarray) – 2D array of X coordinates from detect_ground.

  • grid_y (np.ndarray) – 2D array of Y coordinates from detect_ground.

  • grid_z (np.ndarray) – 2D array of Z values from detect_ground.

  • title (str) – The title for the plot.

libtts.ground_detection.run_ground_detection(infile: str, out_gd_file: str = None, out_veg_file: str = None, grid_size: float = 0.5, height_threshold: float = 0.5, **ground_detection_params) list[str, str][source]

Runs the full ground detection workflow and saves the results.

Parameters:
  • infile (str) – Path to the input point cloud file (.pts or .txt).

  • out_gd_file (str, optional) – Path to save ground points.

  • out_veg_file (str, optional) – Path to save vegetation points.

  • grid_size (float) – Size of the grid cells for DTM generation.

  • height_threshold (float) – Height threshold to classify vegetation.

  • include (ground_detection_params) –

    • outlier_std_dev (float): Std deviations for outlier removal.

    • gaussian_kernel_size (int): Kernel size for smoothing.

Returns:

A list containing:

  • Path to the saved ground points file.

  • Path to the saved vegetation points file.

Return type:

list[str,str]

Tree Detection Functions

Tree Detection

Functions for detecting potential tree locations from a normalized point cloud.

Example

# simple tree detection
tree_locfile = libtts.run_tree_detection(
    infile="tls_veg_file.pts",
    outfile="tree_locations.pts",
    method='base',
    height_min=0.5,
    height_max=1.0,
    max_avg_dist=1.0,
    eps=0.2,
    min_samples=5
)

# geometry-based tree detection
tree_locfile = libtts.run_tree_detection(
    infile="out_ply_file.ply",
    outfile="tree_locations.pts",
    method='geometry',
    height_min=0.5,
    height_max=1.0,
    n_neighbors_pca=20,
    max_linearity=0.2,
    max_knn_dist=0.02,
    eps=0.1,
    min_samples=20
)

# gridding-based tree detection
tree_locfile = libtts.run_tree_detection(
    infile="ptsfile.pts",
    outfile="tree_locations_gridding.pts",
    method='grid',
    height_min=0.5,
    height_max=1.0,
    grid_size=0.05,
    eps=0.1,
    min_samples=2,
    does_plot=True
)
libtts.tree_detection.cluster_points_dbscan(points: ndarray, eps: float = 0.2, min_samples: int = 10, use_2d: bool = True) ndarray[source]

Clusters points using DBSCAN and returns points with cluster labels.

It can perform clustering in either 2D (XY) or 3D (XYZ). Noise points (as defined by DBSCAN) are discarded.

Parameters:
  • points (np.ndarray) – The input points to cluster.

  • eps (float) – The maximum distance between two samples for one to be considered as in the neighborhood of the other.

  • min_samples (int) – The number of samples in a neighborhood for a point to be considered as a core point.

  • use_2d (bool) – If True, clustering is performed on the first two columns (XY). If False, it’s performed on the first three (XYZ).

Returns:

An array containing the original points that belong to a cluster, with a new column appended for the cluster label. Labels start from 1. Returns an empty array if no clusters are found.

Return type:

np.ndarray

libtts.tree_detection.detect_trees_by_base_density(points_xyzh: ndarray, **kwargs) ndarray[source]

Workflow to detect trees by filtering for dense points and clustering.

This high-level function follows a simple tree detection workflow:

  1. Filters points to find dense areas in a low height range.

  2. Clusters the resulting points using DBSCAN.

Parameters:
  • points_xyzh (np.ndarray) – The input Nx4 (XYZH) point cloud.

  • **kwargs – Keyword arguments passed to filter_tree_bases and cluster_points_dbscan. See those functions for details.

Returns:

An array of labeled tree points (x, y, z, h, label).

Return type:

np.ndarray

libtts.tree_detection.detect_trees_by_geometry(points_xyzh: ndarray, **kwargs) ndarray[source]

Workflow to detect trees by filtering on geometry and clustering.

This high-level function follows a geometry-based tree detection workflow:

  1. Filters points based on local geometry (linearity and density).

  2. Clusters the resulting points using DBSCAN.

Parameters:
  • points_xyzh (np.ndarray) – The input Nx4 (XYZH) point cloud.

  • **kwargs – Keyword arguments passed to filter_points_by_geometry and cluster_points_dbscan. See those functions for details.

Returns:

An array of labeled tree points (x, y, z, h, label).

Return type:

np.ndarray

libtts.tree_detection.detect_trees_by_gridding(points_xyzh: ndarray, **kwargs) ndarray[source]

Workflow that uses a 2D histogram (gridding) to find and cluster trees.

This method works by:

  1. Creating a 2D histogram of point counts in a specified height slice.

  2. Identifying “dense” grid cells that contain many points.

  3. Clustering these dense grid cells using DBSCAN.

  4. Labeling the original points based on the cluster of the cell they fall into.

Parameters:
  • points_xyzh (np.ndarray) – The input Nx4 (XYZH) point cloud.

  • height_min (float) – The minimum height for the analysis slice. Default is 0.5.

  • height_max (float) – The maximum height for the analysis slice. Default is 1.0.

  • grid_size (float) – The size of each grid cell in meters. Default is 0.05.

  • min_points_per_cell (int) – The minimum number of points required in a grid cell to consider it “dense”. Default is 100.

  • eps (float) – The maximum distance between two samples for one to be considered as in the neighborhood of the other (DBSCAN parameter). Default is 0.1.

  • min_samples (int) – The number of samples in a neighborhood for a point to be considered as a core point (DBSCAN parameter). Default is 2.

  • does_plot (bool) – If True, plots the histogram of selected grid cells. Default is False.

Returns:

An array of labeled tree points (x, y, z, h, label).

Return type:

np.ndarray

Raises:

ImportError – If does_plot is True but ‘matplotlib’ is not installed.

libtts.tree_detection.filter_points_by_geometry(points_xyzh: ndarray, height_min: float = 0.5, height_max: float = 1.5, n_neighbors_pca: int = 15, min_linearity: float = 0.0, max_linearity: float = 0.7, max_knn_dist: float = 0.1, knn_for_dist: int = 4) ndarray[source]

Filters points based on local geometric properties (density and linearity).

This function identifies potential tree trunk points by analyzing the geometry of each point’s local neighborhood. It keeps “dense and linear” points that are (min_linearity, max_linearity) and < max_knn_dist. Note: “linearity” is between 0 and 1, where 0 is a perfect line and 1 is a plane.

Parameters:
  • points_xyzh (np.ndarray) – Input Nx4 point cloud (XYZH).

  • height_min (float) – Minimum height for the analysis slice.

  • height_max (float) – Maximum height for the analysis slice.

  • n_neighbors_pca (int) – The number of neighbors to define the local neighborhood for Principal Component Analysis (PCA).

  • min_linearity (float) – The minmum linearity value.

  • max_linearity (float) – The maximum linearity value for a point to be kept. The smaller value, the more linear the points appear.

  • max_knn_dist (float) – The maximum average distance to the k-nearest neighbors for a point to be considered dense.

  • knn_for_dist (int) – The number of neighbors to use for the final density check.

Returns:

An array of filtered points that are dense and not strongly linear. Returns an empty array if no points meet the criteria.

Return type:

np.ndarray

libtts.tree_detection.filter_tree_bases(points_xyzh: ndarray, height_min: float = 0.5, height_max: float = 1.0, knn: int = 4, max_avg_dist: float = 0.1) ndarray[source]

Filters a point cloud to find dense points in a low height range.

  1. isolate points within a specific height slice [height_min, height_max]

  2. filters them based on local density. The density is measured by the average distance to the k-nearest neighbors.

Parameters:
  • points_xyzh (np.ndarray) – An Nx4 array of XYZH points.

  • height_min (float) – The minimum height for the analysis slice.

  • height_max (float) – The maximum height for the analysis slice.

  • knn (int) – The number of nearest neighbors to consider for the density check.

  • max_avg_dist (float) – The maximum average distance to the k-nearest neighbors for a point to be considered dense.

Returns:

An array of filtered points that fall within the height slice and meet the density criteria. Returns an empty array if no points meet the criteria.

Return type:

np.ndarray

libtts.tree_detection.run_tree_detection(infile: str, outfile: str | None = None, method: str = 'base', **kwargs) ndarray | str | None[source]

Runs a complete tree detection workflow on a file.

This is the main entry point function. It loads a point cloud, runs the specified detection method, and either saves the result to a file or returns it as a NumPy array.

Parameters:
  • infile (str) – Path to the input point cloud file (.pts, .txt, .ply).

  • outfile (str, optional) – Path to save the output labeled tree points. If None, the result is returned as an array. Defaults to None.

  • method (str) – The detection method to use. One of ‘base’, ‘geometry’, or ‘grid’. Defaults to ‘base’.

  • **kwargs – Keyword arguments for the underlying detection functions.

Returns:

If outfile is None, returns a NumPy array of labeled points (x,y,z,label). If outfile is provided, returns the output file path as a string. Returns None on failure or if no trees are detected and an outfile is specified.

Return type:

Optional[Union[np.ndarray, str]]

Raises:

ValueError – If an unknown method is specified.

Tree Extraction Functions

These functions are implemented in C++ and wrapped with pybind11 for performance. They are available in the _libtts submodule and wrapped in the main libtts library.

Example Workflow

import libtts

# Example workflow for extracting a single tree
as_file = libtts.generate_alpha_shape(tls_veg_file, th_alpha_sq)

segfile = libtts.tls_extract_single_trees(
    as_file,
    treeloc_file,
    th_p2trunk_distance=0.2,
    th_search_radius=0.25
)

Internal C++ bindings for libTTS

_libtts.generate_alpha_shape_cpp(infile: str, alpha_sq_value: SupportsFloat = 0.01) str

Generates a 3D alpha shape mesh from a point cloud.

This function reads a .pts file, computes the alpha shape and saves the result to a new file. The alpha value controls the level of detail and concavity.

Parameters:
  • infile (str) – Path to the input point cloud file (.pts).

  • alpha_sq_value (float) – The squared alpha value for the computation. A smaller value results in a tighter mesh with more detail and potential holes. A larger value results in a more convex shape. Defaults to 0.01.

Returns:

The path to the generated output mesh file.

Return type:

str

_libtts.get_oversegments_cpp(infile: str) str

Performs over-segmentation on a 3D mesh file.

This function takes a mesh file (e.g., from alpha shape generation) and divides it into a set of smaller subset made by points. The result is a point cloud where each point is assigned a segment ID.

Parameters:

infile (str) – Path to the input mesh file (.ply or .off).

Returns:

The path to the output file containing the segmented point cloud with labels.

Return type:

str

_libtts.tls_extract_single_trees_cpp(vg_mesh_file: str, loc_file: str, th_p2trunk_distance: SupportsFloat = 0.2, th_search_radius: SupportsFloat = 0.25) str

Extracts individual tree point clouds from the vegetation mesh.

Using a vegetation mesh and a file of initial tree trunk locations, this function segments the mesh to isolate the points belonging to each individual tree.

Parameters:
  • vg_mesh_file (str) – Path to the input vegetation mesh file.

  • loc_file (str) – Path to a file containing the tree locations of the tree trunks to be segmented. File format is expected to be a text file with each line containing the x y z l.

  • th_p2trunk_distance (float) – The maximum distance a point can be from a trunk surface to be considered part of that tree. Defaults to 0.2.

  • th_search_radius (float) – The maximum distance a point can be from a trunk center to be considered part of that tree. Defaults to 0.25.

Returns:

The path to the output file containing the points for all extracted single trees, likely with labels.

Return type:

str

Points Downsampling Functions

Points Downsampling

Functions for downsampling point clouds using two distinct methods.

This module provides functionality to reduce the number of points in a point cloud file. It supports two primary strategies:

  1. LAStools-based: A general-purpose random downsampling method that uses the external LAStools ‘las2las’ executable.

  2. Object-based: An algorithm designed for wood-leaf separation in segmented point clouds. It filters points within each segment based on local point density, effectively removing sparse “leaf” points while retaining dense “woody” structures.

Dependencies:
  • numpy

  • plyfile

  • laspy (for LAStools-based method)

  • scikit-learn (for object-based method)

External Dependencies:
  • LAStools: Required for the ‘lastools’ method. The path to the ‘bin’ directory must be provided.

Example

# LAStools-based downsampling to keep 50% of points
ds_file = libtts.run_downsampling(
    method="lastools",
    infile="input.ply",
    lastools_bin="/path/to/lastools/bin/",
    fraction=0.5
)

# Object-based downsampling on a pre-segmented point cloud
woody_pts_file = libtts.run_downsampling(
    method="object_based",
    infile="oversegmented_tree.pts",
    input_type="overseg",
    distance_threshold=0.1
)

# Object-based downsampling starting from a raw point cloud (requires C++ module)
woody_pts_file_from_raw = libtts.run_downsampling(
    method="object_based",
    infile="raw_tree.pts",
    input_type="pts",
    alpha_sq=0.01,
    distance_threshold=0.1
)
libtts.points_downsampling.downsample_by_lastools(infile: str, lastools_bin_dir: str, keep_random_fraction: float) str[source]

Downsamples a point cloud file by a random fraction using LAStools.

This method performs a multi-step process:

  1. Converts the input file (.ply, .pts) to a temporary LAS file if needed.

  2. Calls the las2las executable to perform random downsampling.

  3. Converts the downsampled LAS file back to a PLY file for the final output.

Parameters:
  • infile (str) – Path to the input file (.ply, .las, or .pts).

  • lastools_bin_dir (str) – Path to the LAStools ‘bin’ directory.

  • keep_random_fraction (float) – The fraction of points to keep (e.g., 0.1 for 10%).

Returns:

The path to the final, downsampled .PLY output file.

Return type:

str

Raises:
  • ImportError – If the ‘laspy’ library is not installed.

  • FileNotFoundError – If the ‘las2las’ or ‘txt2las’ executable is not found.

  • RuntimeError – If a LAStools command fails.

  • ValueError – If the input file format is unsupported.

  • NotImplementedError – If run on a non-Linux environment.

libtts.points_downsampling.downsample_object_based(infile: str, th_avg_dis: float, num_processes: int = 8) str[source]

Filters a labeled point cloud to separate woody from leafy points.

This function reads a point cloud with labels (e.g., from an oversegmentation result), groups points by their label, and then filters each group in parallel. The filtering keeps points in dense clusters, effectively removing sparse “leaf” points.

Parameters:
  • infile (str) – Path to the input point cloud file (.pts or .ply with labels). The file must contain XYZ and label data.

  • th_avg_dis (float) – The average distance threshold for classifying a point as “woody”.

  • num_processes (int) – The number of CPU cores to use for parallel processing.

Returns:

The path to the output file containing the filtered “woody” points.

Return type:

str

Raises:
  • ImportError – If ‘scikit-learn’ is not installed.

  • ValueError – If the input file format is not supported, if it lacks a ‘label’ property, or if no points are selected after filtering.

  • FileNotFoundError – If the input file does not exist.

libtts.points_downsampling.downsample_object_based_from_mesh(infile, th_avg_dis=0.1)[source]

Runs oversegmentation on a mesh file, then downsamples the result.

This function provides a workflow for mesh inputs. It first calls a C++ backend function to perform oversegmentation on the mesh, then passes the resulting labeled point cloud to the object-based downsampler.

Parameters:
  • infile (str) – Path to the input mesh file.

  • th_avg_dis (float) – The average distance threshold passed to the final downsampling step. Defaults to 0.1.

Returns:

The path to the final “woody” points file.

Return type:

str

Raises:

NotImplementedError – If the required C++ module is not available.

libtts.points_downsampling.downsample_object_based_from_points(infile, th_alpha_sq=0.01, th_avg_dis=0.1)[source]

Runs a full wood-leaf separation workflow from a raw point cloud.

This function orchestrates a multi-step C++ pipeline:

  1. Generates an alpha shape from the raw points.

  2. Performs oversegmentation on the resulting mesh.

  3. Passes the labeled point cloud to the object-based downsampler.

Parameters:
  • infile (str) – Path to the input raw point cloud file (.pts).

  • th_alpha_sq (float) – Alpha squared value for alpha shape generation. Defaults to 0.01.

  • th_avg_dis (float) – The average distance threshold for the final downsampling step. Defaults to 0.1.

Returns:

The path to the final “woody” points file.

Return type:

str

Raises:

NotImplementedError – If the required C++ module is not available.

libtts.points_downsampling.run_downsampling(method: str, **kwargs)[source]

High-level wrapper to run the selected downsampling method.

This function acts as a dispatcher, calling the appropriate low-level downsampling function based on the specified method and its arguments.

Parameters:
  • method (str) – The downsampling method to use (‘lastools’ or ‘object_based’).

  • **kwargs – Keyword arguments for the underlying methods. For ‘lastools’, requires: infile (str), lastools_bin (str), and fraction (float). For ‘object_based’, requires: infile (str), input_type (str), and th_avg_dis (float).

Returns:

The path to the output file.

Return type:

str

Raises:

ValueError – If the method is unknown or required arguments are missing.

Label Propagation Functions

Label Propagation

Propagates labels from a small set of seed points to a larger point cloud.

This module provides two primary methods for label propagation:

  1. Region Growing: A method that starts from seed points and “grows” regions outwards, labeling neighbors within a specified radius. It processes points in ascending Z-height order to ensure a bottom-up propagation, which is useful for environments like forests.

  2. Layered Nearest Neighbor: A faster, more constrained method that divides the point cloud into horizontal layers. It labels points in each layer based on the nearest labeled seed within that same layer, but only if the seed is within a maximum search radius.

Example

import libtts

# Using the Z-ordered region growing method
labels = libtts.run_label_propagation(
    infile="unlabeled_cloud.ply",
    labeled_file="tree_locations.pts",
    method='region_growing',
    search_radius=0.5,
    out_file="cloud_labeled_region_growing.ply"
)

# Using the faster, layered nearest neighbor method
labels_nn = libtts.run_label_propagation(
    infile="unlabeled_cloud.ply",
    labeled_file="tree_locations.pts",
    method='layered_nn',
    layer_height=1.0,
    max_search_radius=1.0,
    out_file="cloud_labeled_layered_nn.ply"
)
libtts.label_propagation.label_points_layered_nn(points: ndarray, labeled_seed_points: ndarray, layer_height: float = 1.0, max_search_radius: float = 1.0, out_file: str | None = None) ndarray[source]

Labels unlabeled points using a layered Nearest Neighbor approach.

This method processes the point cloud in horizontal layers from bottom to top. For each layer, it finds the nearest labeled seed point for every unlabeled point within that same layer. A label is only propagated if the seed point is within the max_search_radius.

Parameters:
  • points (np.ndarray) – The target Nx3 (X,Y,Z) point cloud to be labeled.

  • labeled_seed_points (np.ndarray) – An Mx4 (X,Y,Z,label) array of initially labeled points.

  • layer_height (float) – The thickness of each horizontal layer for processing.

  • max_search_radius (float) – The maximum distance to a labeled point for propagation to occur.

  • out_file (str, optional) – If provided, saves the final labeled points (X,Y,Z,label) to this path. Supports .ply and .pts. Defaults to None.

Returns:

An array of shape (N,) containing the propagated labels for the target ‘points’ cloud. Unlabeled points will have a value of -1.

Return type:

np.ndarray

libtts.label_propagation.label_points_region_growing(points: ndarray, labeled_seed_points: ndarray, search_radius: float = 0.5, out_file: str | None = None) ndarray[source]

Labels unlabeled points using a region growing method ordered by Z-height.

This method works by starting with initial seed points and iteratively “growing” their labels outwards to neighboring points. A priority queue ensures that points with lower Z-coordinates are processed first, creating a bottom-up labeling effect.

Parameters:
  • points (np.ndarray) – The target Nx3 (X,Y,Z) point cloud to be labeled.

  • labeled_seed_points (np.ndarray) – An Mx4 (X,Y,Z,label) array of initially labeled points.

  • search_radius (float) – The maximum distance to consider points as “connected” neighbors for region growing.

  • out_file (str, optional) – If provided, saves the final labeled points (X,Y,Z,label) to this path. Supports .ply and .pts. Defaults to None.

Returns:

An array of shape (N,) containing the propagated labels for the target ‘points’ cloud. Unlabeled points will have a value of -1.

Return type:

np.ndarray

libtts.label_propagation.run_label_propagation(infile: str, labeled_file: str, method: str = 'region_growing', **kwargs) ndarray[source]

Runs label propagation on a point cloud using the specified method.

This high-level function loads the necessary point cloud files and dispatches to the appropriate labeling algorithm.

Parameters:
  • infile (str) – Path to the input point cloud file to be labeled (.pts or .ply).

  • labeled_file (str) – Path to the file containing the labeled seed points (.pts or .ply with X,Y,Z,label).

  • method (str) – The method to use for label propagation. One of ‘region_growing’ or ‘layered_nn’. Defaults to ‘region_growing’.

  • **kwargs – Additional keyword arguments to be passed to the chosen labeling function (e.g., search_radius, layer_height).

Returns:

The array of labels for the input point cloud.

Return type:

np.ndarray

Raises:
  • ValueError – If an unsupported file format or method is provided.

  • FileNotFoundError – If either input file cannot be found.