Skip to content

Project Point Cloud to Plane

SUMMARY

Project Point Cloud to Plane orthogonally projects every point of a 3D point cloud onto a plane, flattening the cloud onto that surface.

Each point is moved to its closest point on the plane ax + by + cz + d = 0, defined by the coefficients [a, b, c, d] you supply ([a, b, c] is the plane normal and d is the signed distance from the origin — often obtained from a plane-fitting skill such as segment_point_cloud_using_plane). This is the same operation as project_point_cloud_to_plane_defined_by_point_normal, just parameterized differently — use this variant when you already have [a, b, c, d] coefficients rather than a point-and-normal pair.

Use this Skill when you want to flatten a 3D point cloud onto a known plane for ground-plane removal, planar feature extraction, or preparing data for 2D-style analysis.

The Skill

python
from telekinesis import vitreous

projected_point_cloud = vitreous.project_point_cloud_to_plane(
    point_cloud=point_cloud,
    plane_coefficients=[0.0, 0.0, 1.0, 0.0],
    add_white_noise=False,
    white_noise_standard_deviation=0.0,
)
API Reference
Full parameter and return type documentation for project_point_cloud_to_plane.
View Reference →

Data Transfer Notice

There is no longer a fixed limit of 1 million points per request. However, very large datasets may result in slower data transfer and processing times. We are continuously optimizing performance as part of our beta program, with ongoing improvements to enhance speed and reliability.

Example

Raw Pointcloud

Unprocessed point cloud. Plane for projection visualized in green.

Projected Pointcloud

Flattened pointcloud.

The Code

python
"""
Demonstrates projecting a point cloud orthogonally onto a plane.
"""

from loguru import logger
import rerun as rr

from telekinesis import vitreous, datatypes


def project_point_cloud_to_plane_example():
    """
    Projects all points orthogonally onto a plane.

    Moves each point to its closest point on the specified plane. Flattens
    the cloud onto a 2D surface in 3D space.
    """
    # ===================== Load Data ==========================================
    point_cloud_url = (
        "https://assets.telekinesis.ai/examples/v1/point_clouds/engine_parts_0.ply"
    )
    point_cloud = datatypes.PointCloud.from_url(url=point_cloud_url, use_cache=True)

    # ===================== Run Skill ==========================================
    projected_point_cloud = vitreous.project_point_cloud_to_plane(
        add_white_noise=False,
        white_noise_standard_deviation=1e-6,
        point_cloud=point_cloud,
        plane_coefficients=[0.0, 0.0, 1.0, 0.0],
    )

    # ===================== Log ================================================
    logger.success(f"Projected {point_cloud} to plane")
    logger.success(f"Results: {projected_point_cloud}")
    logger.info(
        f"Projected point cloud positions shape: {projected_point_cloud.positions.shape}"
    )
    logger.info(
        f"Projected point cloud has normals shape: "
        f"{projected_point_cloud.normals.shape if projected_point_cloud.has_normals else None}"
    )
    logger.info(
        f"Projected point cloud has colors shape: "
        f"{projected_point_cloud.colors.shape if projected_point_cloud.has_colors else None}"
    )

    # ===================== Visualization  (Optional) ===========================
    rr.init("project_point_cloud_to_plane_example", spawn=True)
    datatypes.visualize(point_cloud, entity_path="/1-input_point_cloud")
    datatypes.visualize(projected_point_cloud, entity_path="/2-filtered_point_cloud")


if __name__ == "__main__":
    project_point_cloud_to_plane_example()

Runnable examples are available in the Telekinesis examples repository.

Follow the README in that repository to set up the environment, run this specific example with:

bash
cd telekinesis-examples
python examples/point_cloud/project_point_cloud_to_plane.py

Parameter Configuration

These parameters are passed directly to the plane-projection service and control which plane the cloud is projected onto, and whether synthetic noise is added to the result.

KeyTypeDefaultDescription
point_clouddatatypes.PointCloudrequiredThe point cloud to project
plane_coefficientsdatatypes.Vector4D | np.ndarray | list[float]requiredThe plane equation coefficients [a, b, c, d] where ax + by + cz + d = 0. [a, b, c] is the plane normal (should be normalized) and d is the signed distance from the origin. Often obtained from a plane-fitting skill such as segment_point_cloud_using_plane
add_white_noisedatatypes.Bool | boolFalseWhether to add random Gaussian noise to the projected points, e.g. to simulate measurement uncertainty when generating synthetic test data
white_noise_standard_deviationdatatypes.Float | float | int0.0Standard deviation, in meters, of the Gaussian noise added when add_white_noise is True; ignored otherwise

Returns

TypeDescription
datatypes.PointCloudA point cloud with every point moved onto the plane. Use .positions for the projected (N, 3) position array.

Raises

ExceptionCondition
TypeErrorA parameter's value does not match its expected type (see the Parameter Configuration table above)
ValueErrorplane_coefficients does not have exactly 4 elements
ConfigurationErrorThe TELEKINESIS_API_KEY environment variable is not set
SerializationErrorThe request input failed to serialize, or the response failed to deserialize
RequestTimeoutErrorThe request to the Vitreous service timed out
TransportErrorA network failure occurred before a response was received
ClientErrorThe Vitreous service rejected the request due to invalid input, invalid data, or another unexpected 4xx response
AuthenticationErrorThe API key was rejected as invalid or expired
AuthenticationServiceErrorThe authentication service was unavailable
ServerErrorThe Vitreous service returned a 5xx or otherwise unexpected error response

How to Tune the Parameters

plane_coefficients

  • Controls: Which plane, in the general form ax + by + cz + d = 0, the point cloud is projected onto.
  • Units: [a, b, c] dimensionless (unit normal); d in meters
  • Default: required, no default
  • Normalize [a, b, c] to unit length before passing it in — an un-normalized normal still describes the same plane geometrically, but d then loses its meaning as a distance in meters
  • Obtain these directly from a plane-fitting skill such as segment_point_cloud_using_plane rather than hand-deriving them

add_white_noise

  • Controls: Whether Gaussian noise is added to the projected points after they are moved onto the plane.
  • Units: Boolean
  • Default: False
  • Keep False for exact, deterministic projection
  • Set True only to synthesize noisy test data, e.g. to simulate sensor measurement uncertainty

white_noise_standard_deviation

  • Controls: The spread of the Gaussian noise added when add_white_noise=True. Ignored when add_white_noise=False.
  • Units: Meters
  • Default: 0.0
  • Increase → more variation around the projected plane position
  • Decrease → projected points stay closer to the exact plane
  • Typical range: 0.0–0.01 meters — use 0.001–0.005 for small variation, 0.005–0.01 for larger variation

TIP

Keep add_white_noise=False for exact projection; only enable noise for simulation/testing. If you don't already have plane coefficients, run segment_point_cloud_using_plane first to obtain them.

Where to Use the Skill

Common pipelines include:

  • Ground plane removal – flattening a floor/table scan onto its best-fit plane before filtering out ground points
  • Planar feature extraction – reducing a near-planar surface to a true 2D-in-3D representation for shape or area analysis
  • Conveyor/inspection alignment – projecting scanned parts onto a known reference plane (e.g. a conveyor belt) before measurement
  • Registration preparation – standardizing point clouds onto a common plane before running registration or segmentation

Alternative Skills

Skillvs. Project Point Cloud to Plane
project_point_cloud_to_plane_defined_by_point_normalProjects onto the exact same kind of plane, just specified by a point + normal instead of [a, b, c, d] coefficients. Use whichever parameterization you already have on hand — the two are otherwise equivalent.

When Not to Use the Skill

Do not use Project Point Cloud to Plane when:

  • You have a point and normal vector instead of [a, b, c, d] coefficients — use project_point_cloud_to_plane_defined_by_point_normal directly rather than converting
  • You need to preserve full 3D structure — projection flattens the cloud onto the plane, discarding out-of-plane detail
  • You need a non-orthogonal projection — this Skill only performs orthogonal (closest-point) projection
  • plane_coefficients isn't normalized or well-formed — a non-unit [a, b, c] still defines a valid plane geometrically, but d will no longer read as a distance in meters

TIP

If you don't have plane coefficients yet, run segment_point_cloud_using_plane first — its output can be fed directly into plane_coefficients here.