Main Content


Segment ground points from organized lidar data



groundPtsIdx = segmentGroundFromLidarData(ptCloud) segments organized 3-D lidar data, ptCloud, into ground and nonground parts. The lidar sensor must be mounted horizontally such that all ground points are observed in the lidar scan closest to the sensor.

To use this function, the ground plane must be along the x-y plane. You can use the pctransform to rotate the sensor data before using segmentGroundFromLidarData.

groundPtsIdx = segmentGroundFromLidarData(ptCloud,Name=Value) sets properties using one or more name-value pairs. Enclose each property name in quotes. For example, segmentGroundFromLidarData(ptCloud,ElevationAngleDelta=5)


collapse all

Segment ground points and nonground points from an organized lidar point cloud. Create organized point clouds from these segmentations, and display them.

Load an organized lidar, point cloud.

ld = load('drivingLidarPoints.mat');

Segment ground points from the organized lidar point cloud.

groundPtsIdx = segmentGroundFromLidarData(ld.ptCloud);

Create an organized point cloud containing only these ground points by using the select function. Display this point cloud.

groundPtCloud = select(ld.ptCloud,groundPtsIdx);

Create an organized point cloud containing only the nonground points. Specify a threshold of 0.5 meters.

nonGroundPtCloud = select(ld.ptCloud,~groundPtsIdx,'OutputSize','full');
distThreshold = 0.5;   
[labels,numClusters] = segmentLidarData(nonGroundPtCloud,distThreshold);  

Display the nonground points cloud clusters.

title('Point Cloud Clusters')

Load Velodyne PCAP® to the workspace.

velodyneFileReaderObj = velodyneFileReader('lidarData_ConstructionRoad.pcap','HDL32E');

Create a point cloud player using pcplayer. Define its x-, y-, and z-axes limits, in meters, and label its axes.

xlimits = [-40 40];
ylimits = [-15 15];
zlimits = [-3 3];
player = pcplayer(xlimits,ylimits,zlimits);

Label the pcplayer axes.

xlabel(player.Axes,'X (m)')
ylabel(player.Axes,'Y (m)')
zlabel(player.Axes,'Z (m)')

Set the colormap for labeling points. Use RGB triplets to specify green for ground-plane points, and red for obstacle points.

colors = [0 1 0; 1 0 0]; 
greenIdx = 1;
redIdx = 2;

Iterate through the point clouds in the Velodyne PCAP file, using readFrame to read in the data. Segment the ground points from each point cloud. Color all ground points green and nonground points red. Plot the resulting lidar point cloud.

title(player.Axes,'Segmented Ground Plane of Lidar Point Cloud');

for i = 1:velodyneFileReaderObj.NumberOfFrames
    % Read current frame.
    ptCloud = velodyneFileReaderObj.readFrame(i);

    % Create label array.
    colorLabels = zeros(size(ptCloud.Location,1),size(ptCloud.Location,2));

    % Find the ground points.
    groundPtsIdx = segmentGroundFromLidarData(ptCloud);

    % Map color ground points to green.
    colorLabels(groundPtsIdx (:)) = greenIdx;

    % Map color nonground points to red.
    colorLabels(~groundPtsIdx (:)) = redIdx;

    % Plot the results.

Input Arguments

collapse all

Point cloud, specified as a pointCloud object. ptCloud is an organized point cloud that stores [x,y,z] point coordinates in an M-by-N-by-3 matrix.

Name-Value Arguments

Example: ElevationAngleDelta=5 sets the elevation angle threshold to 5 degrees.

Elevation angle difference threshold to identify ground points, specified as a nonnegative scalar. The function computes the elevation angle difference between one labeled ground point and its 4-connected neighbors. The neighborhood point is labeled as ground if the difference is below the threshold. Typical values for ElevationAngleDelta are in the range of [5,15] degrees. Increase this value to encompass more points from uneven ground surfaces.

Initial elevation angle threshold to identify the ground point in the scanning line closest to the lidar sensor, specified as a non-negative scalar. The function marks a point as ground when the elevation angle falls below this value. Typical values for InitialElevationAngle are in the range of 15 and 30 degrees.

Output Arguments

collapse all

Ground points index, returned as an M-by-N logical matrix. Elements with a true value, 1, indicate ground points. Elements with a false value, 0, indicate nonground points.


[1] Bogoslavskyi, I. “Efficient Online Segmentation for Sparse 3D Laser Scans.” Journal of Photogrammetry, Remote Sensing and Geoinformation Science. Vol. 85, Number 1, 2017, pp. 41–52.

Extended Capabilities

C/C++ Code Generation
Generate C and C++ code using MATLAB® Coder™.

Version History

Introduced in R2018b