Ground Filter Tutorial#
Background#
In previous tutorials we introduced our implementation of the Progressive Morphological Filter (PMF), a ground kernel to simplify command-line access to PMF, and a filter for removing outliers.
This tutorial will highlight some recent enhancements to the PDAL library, in the context of a ground segmentation workflow. Specifically, we will discuss:
Constructing and executing a “filters-only” pipeline
Resetting existing classifications prior to processing
Using Extended Local Minimum (ELM) to identify low outliers
Using Simple Morphological Filter (SMRF) as an alternative to PMF
Ignoring outliers during ground segmentation
Considering only last returns during ground segmentation
Extracting ground returns as a post-processing step
Note
The pipeline discussed in this tutorial requires PDAL v1.5.
The Pipeline#
Begin by creating a new file called pipeline.json
with the following
contents.
1{
2 "pipeline":[
3 {
4 "type":"filters.reprojection",
5 "out_srs":"EPSG:32632"
6 },
7 {
8 "type":"filters.assign",
9 "value":"Classification = 0"
10 },
11 {
12 "type":"filters.elm"
13 },
14 {
15 "type":"filters.outlier"
16 },
17 {
18 "type":"filters.smrf",
19 "returns":"last",
20 "where":"!(Classification == 7)",
21 "slope":0.2,
22 "window":16,
23 "threshold":0.45,
24 "scalar":1.2
25 },
26 {
27 "type":"filters.expression",
28 "expression":"Classification == 2"
29 }
30 ]
31}
Note
For users familiar with PDAL pipelines, this example may seem to be missing a couple of very important stages, namely the reader and writer! A new feature of PDAL is the ability to provide a PDAL pipeline with no reader or writer stages to the translate command. The input and output filenames can be specified on the command line and will be automatically inserted into the pipeline by the application.
The Explanation#
We continue by explaining the various stages of the pipeline in order.
Reprojecting Data#
Many of PDAL’s default parameters are specified in meters, and individual filter stages typically assume that units are at least uniform in X, Y, and Z. Because data will not always be provided in this way, PDAL pipelines should account for any data reprojections and parameter scaling that are required from one dataset to the next.
3 {
4 "type":"filters.reprojection",
5 "out_srs":"EPSG:32632"
6 },
In this example, we show data being reprojected to EPSG:32632
with X, Y, and
Z in meters.
Assigning Classification Values#
Let’s assume that you have been given an LAS file that contains per point classifications, but you’d like to start with a clean slate and derive your own classifications with your PDAL pipeline.
PDAL’s assign filter has been added to assign values to
a given dimension. In our example, a single option has been provided that
specifies the dimension, range, and value to assign. In this case, we are
stating that we would like to apply a value of 0 to the Classification
dimension for every point.
7 {
8 "type":"filters.assign",
9 "value":"Classification = 0"
10 },
Note
Previously, you could do the same thing (with a slightly different syntax)
using filters.attribute
, but this filter has been deprecated and split
into filters.assign and filters.overlay.
Extended Local Minimum#
The Extended Local Minimum (ELM) method helps to identify
low noise points that can adversely affect ground segmentation algorithms. ELM
was first published in [Chen et al., 2012] as part of the upward-fusion method of DTM
generation. Noise points are classified with a value of 7
in keeping
with the LAS specification.
11 {
12 "type":"filters.elm"
13 },
Outliers#
PDAL’s outlier filter provides two methods of outlier
detection at the moment: radius
and statistical
. Both aim to identify
points that are isolated and likely arise from noise sources. Noise points are
classified with a value of 7
in keeping with the LAS specification.
14 {
15 "type":"filters.outlier"
16 },
Ground Segmentation#
The Simple Morphological Filter (SMRF) [Pingel et al., 2013] is a newer addition to PDAL that has quietly existed in an alpha state since v1.3. With the release of PDAL v1.5, our SMRF implementation is much more complete, although it only implements nearest neighbor void filling and not the authors’ preferred “Springs” algorithm.
The changes to SMRF between PDAL v1.3 and v1.5 are substantial. The original version had actually drifted quite far from the authors’ published approach, namely in the area of filling voids. We have reverted the code to match the published work, but for now are only using the nearest neighbors approach to filling voids. The morphological operations are also accelerated by moving to an iterative approach and using a diamond structuring element.
17 {
18 "type":"filters.smrf",
19 "returns":"last",
20 "where":"!(Classification == 7)",
21 "slope":0.2,
22 "window":16,
23 "threshold":0.45,
24 "scalar":1.2
25 },
In addition to specifying some of the SMRF-specific arguments, our example also
demonstrates the use of two optional pre-filtering capabilities: ignore
and
last
.
The ignore
option accepts a range, here indicating that we
have points marked as noise (i.e., Classification
of 7) that should be
excluded from ground segmentation, but are kept as part of the output dataset.
The last
option, when set to true
indicates that we would like to only
consider last returns for ground segmentation when return information is
available. Again, returns that are not “last returns” are still retained in the
output dataset - they are simply ignored for the purposes of ground
segmentation.
Note
Many lidar systems provide return information. This includes the number of returns per pulse and the order of a particular return within the pulse. Where the return number and number of returns are equal, we call this a last return.
Last returns are not by definition ground returns. In fact, the first and only return from surfaces such as rooftops will also be last returns, and last returns within dense foliage may not ever make it all the way to ground. Still, whenever there are multiple returns within a pulse, it stands to reason that anything before the last return would not be from the ground.
Some bare earth algorithms explicitly operate on last returns only. In this
case, this logic will presumably be implemented within the filter stage
itself. That being said, it stands to reason that any ground segmentation
approach could be improved by excluding all returns but the so-called last
returns. Neither PMF nor SMRF make this assertion, but our implementations
still consider only last returns by default. This behavior can be changed by
setting last=false
.
For an example of how to filter on last returns outside the context of SMRF and PMF, see this within PDAL’s source tree.
Note
SMRF is not intended to be a replacement for the Progressive Morphological Filter (PMF) [Zhang et al., 2003]. Rather, it is
offered as an alternative. PMF has been a part of PDAL since v1.0, first as
part of the PCL plugin and now as filters.pmf
. Since PDAL v1.4, we have
fixed a number of bugs, and have accelerated the approximate mode by
implementing iterative morphological operations and using a diamond
structuring element.
Extracting Ground Returns#
Any time we have points classified as ground, we may wish to extract just these points, e.g., to create a digital terrain model (DTM). In this case, we use a range filter as shown.
26 {
27 "type":"filters.expression",
28 "expression":"Classification == 2"
29 }
The range filter accepts a limits
option that
identifies the dimension(s) on which to filter and the range of
values to passthrough. In this case, we are indicating that the filter should
only pass points whose Classification
value is equal to 2.
Note
The default behavior of both PMF and SMRF is to classify points, which has not changed from previous
versions of PDAL. The extract
and classify
options have been removed
in PDAL v1.5. These filters now only classify points, such that ground
points can be identified and filtered downstream, as we have shown with the
range filter above.
Running the Pipeline#
Now let’s run our pipeline.json
example, using it to
translate input.las
to output.las
.
$ pdal translate input.las output.las --json pipeline.json