Segment ground from lidar data using a SMRF algorithm
Segment Ground in Aerial Lidar Data
Segment the ground in an unorganized aerial point cloud.
lasFileReader object to access the data of
fileName = fullfile(toolboxdir("lidar"),"lidardata","las", ... "aerialLidarData2.las"); lasReader = lasFileReader(fileName);
Read the point cloud data from the LAS file using the
ptCloud = readPointCloud(lasReader);
Segment the ground data from the point cloud.
[groundPtsIdx,nonGroundPtCloud,groundPtCloud] = segmentGroundSMRF(ptCloud);
Visualize the ground and nonground points.
Segment and Remove Ground from Point Cloud Data
Segment and remove the ground from an organized point cloud. The point cloud was captured in a highway scenario.
Load the point cloud data into the workspace.
ld = load("drivingLidarPoints.mat");
Display the input point cloud.
pcshow(ld.ptCloud) xlim([-40 40]) ylim([-50 50])
Segment the ground data from the point cloud.
[~,nonGroundPtCloud,groundPtCloud] = segmentGroundSMRF( ... ld.ptCloud,MaxWindowRadius=5,ElevationThreshold=0.1,ElevationScale=0.25);
Visualize the nonground points.
figure pcshow(nonGroundPtCloud) xlim([-40 40]) ylim([-50 50])
gridResolution — Dimension of each grid element
1 (default) | positive scalar
Dimension of each grid element, specified as a positive scalar. The function samples the input point cloud into grids along the xy-direction using the grid size to create a minimum surface map. Decreasing the value of grid resolution may return nonground points as ground.
Specify optional pairs of arguments as
the argument name and
Value is the corresponding value.
Name-value arguments must appear after other arguments, but the order of the
pairs does not matter.
Before R2021a, use commas to separate each name and value, and enclose
Name in quotes.
segmentGroundSMRF(ptCloud,ElevationThreshold=0.4) sets the
elevation threshold for identifying nonground points to
MaxWindowRadius — Maximum radius for structuring element
18 (default) | positive integer
Maximum radius for the disc-shaped structuring element in the morphological opening operation, specified as a positive integer. You can segment large buildings as ground by specifying a smaller radius. Increasing this value can increase the computation time of the function.
The default value works effectively for aerial lidar data. For better
performance on terrestrial data, set
MaxWindowRadius to a
smaller value, such as
SlopeThreshold — Slope threshold for identifying grid elements
0.15 (default) | nonnegative scalar
Slope threshold for identifying grid elements as ground or nonground in a minimum
elevation surface map, specified as a nonnegative scalar. The function classifies a
grid element as ground if its slope is less than
Increase this value to classify steeper slopes as ground.
ElevationThreshold — Elevation threshold for identifying points
0.5 (default) | nonnegative scalar
Elevation threshold for identifying points as ground or nonground in the estimated
elevation model, specified as a nonnegative scalar. The function classifies a point as
ground if the elevation difference between the point and estimated ground surface is
ElevationThreshold. To include more points from bumpy
ground, increase this value.
The default value works effectively for aerial lidar data. For best results on
terrestrial data, set
ElevationThreshold to a smaller value,
ElevationScale — Elevation threshold scaling factor
1.25 (default) | nonnegative scalar
Elevation threshold scaling factor, specified as a nonnegative scalar. You can identify ground points on steep slopes by increasing this value.
groundPtsIdx — Binary map of segmented point cloud
logical matrix | logical vector
Binary map of the segmented point cloud, returned as a logical matrix or a logical vector.
For an organized point cloud of the form M-by-N-by-3,
groundPtsIdxis returned as an M-by-N logical matrix.
For an unorganized point cloud of the form M-by-3,
groundPtsIdxis returned as an M element logical vector.
Elements of this output that correspond to ground points in the point
true and nonground points are
nonGroundPtCloud — Point cloud of nonground points
Point cloud of nonground points, returned as a
groundPtCloud — Point cloud of ground points
Point cloud of ground points, returned as a
A simple morphological filter (SMRF) algorithm  segments point cloud data into ground and nonground points. The algorithm consists of three stages:
Create a minimum elevation surface map from the point cloud data.
Segment the surface map into ground and nonground grid elements.
Segment the original point cloud data.
Create Minimum Elevation Surface Map
Divide the point cloud data into grids along the xy- plane (bird's-eye view). Specify the grid size using
Find the lowest elevation (Zmin) value for each grid element (pixel).
Combine all the Zmin values into a 2-D matrix (raster image) to create a minimum elevation surface map.
Segment Surface Map
Apply a morphological opening operation on the minimum surface map. This applies an erosion filter followed by a dilation filter. For more information on morphological opening, see Types of Morphological Operations.
The shape of the structuring element and its window radius define the search neighbourhood for the morphological opening. Use a disc-shaped structuring element, and start with a window radius of 1 pixel. For more information, see Structuring Elements.
Calculate the slope between the minimum surface and opened surface maps at each grid element. If the difference is greater than the elevation threshold, classify the pixel as nonground.
Execute steps 1 through 3 iteratively. Increase the window radius by 1 pixel in each iteration until it reaches the maximum radius specified by
The end result of the iteration process is a binary mask in which each pixel of the point cloud is classified as either ground or nonground.
Segment Original Point Cloud
Apply the binary mask to the original minimum surface map to remove nonground grids.
Fill the unfilled grids using image interpolation techniques to create an estimated elevation model.
Calculate the elevation difference between each point in the original point cloud and the corresponding point in the estimated elevation model. If the difference is greater than
ElevationThreshold, classify the pixel as nonground.
Multiply the slope of the elevation model at the each point by
ElevationScale, and add the result to the
ElevationThresholdvalue to identify ground points on steep slopes.
 Pingel, Thomas J., Keith C. Clarke, and William A. McBride. “An Improved Simple Morphological Filter for the Terrain Classification of Airborne LIDAR Data.” ISPRS Journal of Photogrammetry and Remote Sensing 77 (March 2013): 21–30.https://doi.org/10.1016/j.isprsjprs.2012.12.002.