Skip to content

Commit ed664d3

Browse files
JanCahawonder-sk
authored andcommitted
remove noise points
1 parent 082e5ce commit ed664d3

File tree

3 files changed

+60
-4
lines changed

3 files changed

+60
-4
lines changed

src/alg.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,7 @@ struct FilterNoise: public Alg
381381
std::string outputFile;
382382
std::string outputFormat; // las / laz / copc
383383
std::string algorithm = "statistical"; // "statistical" or "radius"
384+
bool removeNoisePoints = false;
384385

385386
// radius params
386387
double radiusMinK = 2;
@@ -394,6 +395,7 @@ struct FilterNoise: public Alg
394395
pdal::Arg* argOutput = nullptr;
395396
pdal::Arg* argOutputFormat = nullptr;
396397
pdal::Arg* argAlgorithm = nullptr;
398+
pdal::Arg* argRemoveNoisePoints = nullptr;
397399
pdal::Arg* argRadiusMinK = nullptr;
398400
pdal::Arg* argRadiusRadius = nullptr;
399401
pdal::Arg* argStatisticalMeanK = nullptr;

src/filter_noise.cpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ void FilterNoise::addArgs()
3737
argOutputFormat = &programArgs.add("output-format", "Output format (las/laz/copc)", outputFormat);
3838

3939
argAlgorithm = &programArgs.add("algorithm", "Noise filtering algorithm to use: statistical or radius.", algorithm, "statistical");
40-
40+
argRemoveNoisePoints = &programArgs.add("remove-noise-points", "Remove noise points from the output.", removeNoisePoints, false);
41+
4142
// radius args
4243
argRadiusMinK = &programArgs.add("radius-min-k", "Minimum number of neighbors in radius (radius algorithm only).", radiusMinK, 2.0);
4344
argRadiusRadius = &programArgs.add("radius-radius", "Radius (radius method only).", radiusRadius, 1.0);
@@ -96,7 +97,7 @@ bool FilterNoise::checkArgs()
9697
}
9798

9899

99-
static std::unique_ptr<PipelineManager> pipeline(ParallelJobInfo *tile, pdal::Options &noiseFilterOptions)
100+
static std::unique_ptr<PipelineManager> pipeline(ParallelJobInfo *tile, pdal::Options &noiseFilterOptions, bool removeNoisePoints)
100101
{
101102
std::unique_ptr<PipelineManager> manager( new PipelineManager );
102103

@@ -130,6 +131,13 @@ static std::unique_ptr<PipelineManager> pipeline(ParallelJobInfo *tile, pdal::Op
130131
}
131132

132133
last = &manager->makeFilter("filters.outlier", *last, noiseFilterOptions);
134+
135+
if (removeNoisePoints)
136+
{
137+
Options filter_opts;
138+
filter_opts.add(pdal::Option("expression", "Classification != 7"));
139+
last = &manager->makeFilter( "filters.expression", *last, filter_opts);
140+
}
133141

134142
makeWriter(manager.get(), tile->outputFilename, last);
135143

@@ -180,7 +188,7 @@ void FilterNoise::preparePipelines(std::vector<std::unique_ptr<PipelineManager>>
180188

181189
tileOutputFiles.push_back(tile.outputFilename);
182190

183-
pipelines.push_back(pipeline(&tile, noiseFilterOptions));
191+
pipelines.push_back(pipeline(&tile, noiseFilterOptions, removeNoisePoints));
184192
}
185193
}
186194
else
@@ -189,7 +197,7 @@ void FilterNoise::preparePipelines(std::vector<std::unique_ptr<PipelineManager>>
189197
tile.inputFilenames.push_back(inputFile);
190198
tile.outputFilename = outputFile;
191199

192-
pipelines.push_back(pipeline(&tile, noiseFilterOptions));
200+
pipelines.push_back(pipeline(&tile, noiseFilterOptions, removeNoisePoints));
193201
}
194202
}
195203

tests/test_filter_noise.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,3 +136,49 @@ def test_filter_noise_with_bad_algorithms():
136136

137137
assert res.returncode == 0
138138
assert f"unknown algorithm: {unknown_algorithm}" in res.stderr
139+
140+
141+
def test_filter_noise_statistical_remove_noise_points():
142+
"""Test filter noise function with statistical on laz and removal of noise points"""
143+
144+
input_path = utils.test_data_filepath("stadium-utm.laz")
145+
output_path = utils.test_data_output_filepath("filter_noise_remove_points.laz", "filter_noise")
146+
147+
res = subprocess.run(
148+
[
149+
utils.pdal_wrench_path(),
150+
"filter_noise",
151+
f"--input={input_path.as_posix()}",
152+
f"--output={output_path.as_posix()}",
153+
"--algorithm=statistical",
154+
"--remove-noise-points=true",
155+
],
156+
check=True,
157+
)
158+
159+
assert res.returncode == 0
160+
161+
assert output_path.exists()
162+
163+
pipeline = pdal.Reader(filename=output_path.as_posix()).pipeline()
164+
165+
pipeline.execute()
166+
167+
values = pipeline.arrays[0]["Classification"]
168+
unique_values = np.unique(values)
169+
170+
assert unique_values.size == 2
171+
assert unique_values.tolist() == [1, 2] # 1: non-ground, 2: ground
172+
173+
nonground_point = pipeline.arrays[0][
174+
(pipeline.arrays[0]["X"] == 494629.19000000006) & (pipeline.arrays[0]["Y"] == 4878441.75)
175+
]
176+
assert nonground_point["Classification"] == 1 # non-ground
177+
assert nonground_point["Z"] == 129.14
178+
179+
ground_point = pipeline.arrays[0][(pipeline.arrays[0]["X"] == 494657.37) & (pipeline.arrays[0]["Y"] == 4878358.05)]
180+
assert ground_point["Classification"] == 2 # ground
181+
assert ground_point["Z"] == 130.15999999999997
182+
183+
noise_point = pipeline.arrays[0][(pipeline.arrays[0]["X"] == 494650.53) & (pipeline.arrays[0]["Y"] == 4878439.98)]
184+
assert noise_point.size == 0

0 commit comments

Comments
 (0)