Segment ground points from organized lidar data
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); figure pcshow(groundPtCloud)
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.
figure colormap(hsv(numClusters)) pcshow(nonGroundPtCloud.Location,labels) 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 first 200 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.
colormap(player.Axes,colors) title(player.Axes,'Segmented Ground Plane of Lidar Point Cloud'); for i = 1 : 200 % 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. view(player,ptCloud.Location,colorLabels) end
ptCloud— Point cloud
Point cloud, specified as a
ptCloud is an organized point cloud that stores
coordinates in an M-by-N-by-3 matrix.
'ElevationAngleDelta'— Elevation angle difference threshold
5(default) | nonnegative scalar
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
'InitialElevationAngle'— Initial elevation angle threshold
30(default) | non-negative scalar
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 elevantion angle
falls below this value. Typical values for
InitialElevationAngle are in the range of 15 and
groundPtsIdx— Ground points index
Ground points index, returned as an
M-by-N logical matrix. Elements
1, indicate ground
points. Elements with a
0, indicate nonground points.
 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.
Because of architectural differences between the CPU and GPU, numerical
verification does not always match. The GPU floating-point units use fused
Floating-Point Multiply-Add (FMAD) instructions while the CPU does not use these
instructions. The CUDA® compiler performs these instruction-level optimizations by default
impacting the accuracy of the computed results. For example, the CUDA compiler fuses floating-point multiply and add instructions into a
single instruction. This Floating-point Multiply-Add (FMAD) operation executes twice
as fast compared to two single instructions but results in the loss of numerical
accuracy. You can achieve tighter control over these optimizations by using compiler
flags. For example, passing
--fmad=false to the
Compiler Flags property of the code configuration object
nvcc compiler to disable contraction of
floating-point multiply and add to a single Floating-Point Multiply-Add (FMAD)
instruction. For more information, see Generate Code by Using the GPU Coder App (GPU Coder) .