Skip to main content

Python bindings for TRAVEL: traversable ground and above-ground object segmentation for 3D LiDAR scans

Project description

travel-seg

Python bindings for TRAVEL — traversable ground and above-ground object segmentation for 3D LiDAR scans.

Install

From source (development)

# System deps (Ubuntu)
sudo apt install build-essential cmake libeigen3-dev libpcl-dev \
                 libboost-system-dev libboost-filesystem-dev

# System deps (macOS)
brew install cmake eigen boost pcl

git clone https://github.com/url-kaist/TRAVEL.git
cd TRAVEL
pip install -e python/

From PyPI

pip install travel-seg

The PyPI sdist's python/CMakeLists.txt falls back to FetchContent for the C++ core, so no separate clone is needed. System-side, you still need PCL + Boost + Eigen on the build path — see the system-deps lines in the source-install block above.

Usage

import numpy as np
import travel_seg as ts

# KITTI .bin → (N, 4) float32 XYZI
points = np.fromfile("0000.bin", dtype=np.float32).reshape(-1, 4)

# One-shot
result = ts.segment(points)
ground_pts = points[result.ground_mask]
for cid in np.unique(result.instance_labels):
    if cid == 0:
        continue
    cluster_pts = points[result.instance_labels == cid]
    print(f"cluster {cid}: {len(cluster_pts)} points")

# Per-frame loops: build the segmenters once, reuse
tgs = ts.TravelGroundSeg(ts.GroundSegConfig(max_range=80.0))
aos = ts.ObjectCluster(ts.ObjectClusterConfig(vert_scan=64, horz_scan=4500))
for frame in frames:
    ground_mask, elapsed = tgs.estimate_ground(frame[:, :3])
    labels = aos.segment_objects(frame[~ground_mask, :3])
    ...

API

Symbol Purpose
GroundSegConfig dataclass — TGS parameters; KITTI-tuned defaults
ObjectClusterConfig dataclass — AOS parameters; KITTI-tuned defaults
TravelGroundSeg(cfg) reusable ground segmenter; .estimate_ground(points) -> (mask, elapsed)
ObjectCluster(cfg) reusable object clusterer; .segment_objects(points) -> labels
segment(points, ground_config=None, object_config=None) one-shot helper returning a SegmentResult
SegmentResult dataclass: .ground_mask, .instance_labels, .elapsed_seconds

Inputs are float32 numpy arrays of shape (N, 3) (XYZ) or (N, 4) (XYZI). The intensity column is currently ignored by both TGS and AOS but accepted for convenience when reading raw KITTI bins.

Outputs are length-N numpy arrays aligned with the original input order:

  • ground_mask: bool, True where the input point was classified as ground.
  • instance_labels: int32. 0 = ground / unclassified / dropped. 1..K = per-cluster ids within this single frame (not consistent across frames).

Tests / examples

pip install -e python/[test]
pytest python/tests/

# Real data demo
python python/examples/run_kitti.py /path/to/kitti/sequences/00 0 /tmp/out

Citation

See the top-level README.

Release process

Publishing uses PyPI Trusted Publishing (OIDC), so there are no API tokens or GitHub secrets to manage. PyPI authenticates the GitHub Actions workflow directly based on a one-time pending-publisher registration.

One-time PyPI setup

Visit https://pypi.org/manage/account/publishing/ and add a pending publisher with these values (only required before the very first release; it auto-graduates to a regular trusted publisher after the first upload):

Field Value
PyPI Project Name travel-seg
Owner url-kaist
Repository name TRAVEL
Workflow name release.yml
Environment name pypi

GitHub side: create an environment named pypi at Settings -> Environments (no secrets/protection rules needed unless you want manual approval).

Per-release flow

  1. Bump version in three places to keep them in sync:
    • python/pyproject.toml -> [project] version
    • python/travel_seg/__init__.py -> __version__
    • python/travel_seg/pybind/travel_pybind.cpp -> m.attr("__version__")
  2. Commit, tag, push:
    git commit -am "release: travel-seg vX.Y.Z"
    git tag vX.Y.Z
    git push origin main vX.Y.Z
    
  3. Trigger the Release (PyPI) workflow from the GitHub Actions UI.
  4. Verify the install in a fresh venv:
    python -m venv /tmp/check && source /tmp/check/bin/activate
    pip install travel-seg==X.Y.Z
    python -c "import travel_seg as ts; import numpy as np; \
               ts.segment(np.random.uniform(-10,10,(2000,3)).astype(np.float32))"
    

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

travel_seg-1.0.0.tar.gz (14.0 kB view details)

Uploaded Source

File details

Details for the file travel_seg-1.0.0.tar.gz.

File metadata

  • Download URL: travel_seg-1.0.0.tar.gz
  • Upload date:
  • Size: 14.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for travel_seg-1.0.0.tar.gz
Algorithm Hash digest
SHA256 3f55943ff15c7174aff4c6c731337eaa024a461fb11a2b5cccd5732a644f3bda
MD5 fdcbbe21ae7c8fa36d32a20c9af0bd90
BLAKE2b-256 135ec16e1f674901c9b149940ebcbddb97ad27a7a874cbecb04fc9f7e043d3b2

See more details on using hashes here.

Provenance

The following attestation bundles were made for travel_seg-1.0.0.tar.gz:

Publisher: release.yml on url-kaist/TRAVEL

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page