Segment ground from lidar data using a Simple morphological filter (SMRF) algorithm
Segment the ground in an unorganized aerial point cloud.
lasFileReader object to access the LAS file data.
fileName = fullfile(toolboxdir('lidar'), 'lidardata', 'las', ... 'aerialLidarData2.las'); lasReader = lasFileReader(fileName);
Read point cloud data from the LAS file using the
ptCloud = readPointCloud(lasReader);
Segment ground data from the point cloud.
[groundPtsIdx,nonGroundPtCloud,groundPtCloud] = segmentGroundSMRF(ptCloud);
Visualize the ground and non-ground points.
figure pcshowpair(groundPtCloud, nonGroundPtCloud)
Segment and remove 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 input point cloud.
pcshow(ld.ptCloud) xlim([-40 40]) ylim([-50 50])
Segment ground data from the point cloud.
[~,nonGroundPtCloud,groundPtCloud] = segmentGroundSMRF(..., ld.ptCloud,'MaxWindowRadius',5,'ElevationThreshold',0.1,'ElevationScale',0.25);
Visualize the non-ground 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.
comma-separated pairs of
the argument name and
Value is the corresponding value.
Name must appear inside quotes. You can specify several name and value
pair arguments in any order as
'ElevationThreshold',0.4sets the elevation threshold to identify non-ground points to 0.4.
MaxWindowRadius— Maximum radius of structuring element
18(default) | positive scalar
Maximum radius of the disk-shaped structuring element in the morphological opening operation, specified as a positive scalar. Increase this value to segment large buildings as non-ground at the expense of additional computation.
The default value works effectively for aerial lidar data. For better
performance on terrestrial data, set
MaxWindowRadius to a
smaller value like
SlopeThreshold— Slope threshold to identify non-ground grid elements
0.15(default) | nonnegative scalar
Slope threshold to identify non-ground grid elements in the minimum elevation
surface map, specified as a nonnegative scalar. The function classifies a grid element
as non-ground if its slope is greater than
Increase this value to classify steep slopes as ground.
ElevationThreshold— Elevation threshold to identify non-ground points
0.5(default) | nonnegative scalar
Elevation threshold to identify non-ground points, specified as a nonnegative
scalar. The function classifies a point as non-ground if the elevation difference
between the point and estimated ground surface is greater than
ElevationThreshold. Increase this value to encompass more
points from bumpy ground.
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 with respect to the slope of the estimated ground surface, specified as a nonnegative scalar. Increase this value to identify ground points on steep slopes.
groundPtsIdx— Binary map of segmented point cloud
Binary map of the segmented point cloud, returned as a logical matrix for organized
point clouds, and as a logical vector for unorganized point clouds. The function sets
the locations of ground points in the matrix to
true and non-ground
nonGroundPtCloud— Point cloud of non-ground points
Point cloud of non-ground 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 non-ground points. The algorithm is divided into three stages:
Create a minimum elevation surface from the point cloud data.
Segment the surface into ground and non-ground grid elements.
Segment the original point cloud data.
Minimum Surface Creation
Divide the point cloud data into a grid along the xy-dimension
(bird's eye view). Specify the grid element dimension 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.
Surface Map Segmentation
Apply a morphological opening operation on the minimum surface map. For more information about morphological opening, see Types of Morphological Operations.
Use a disk-shaped structuring element with a 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 elevation threshold, classify the pixel as non-ground.
Execute steps 1 through 3 iteratively. Increase the structuring element 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 where each pixel is classified as being either ground or non-ground.
Point Cloud Segmentation
Apply the binary mask on the original minimum surface map to remove non-ground 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 estimated elevation model. If the difference is greater than
ElevationThreshold, classify the pixel as non-ground.
 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.
The function has a real time performance limitation.