Skip to content

Instantly share code, notes, and snippets.

@wiesehahn
Last active April 17, 2026 07:15
Show Gist options
  • Select an option

  • Save wiesehahn/59fd9c7037213cb058187b805912c5d5 to your computer and use it in GitHub Desktop.

Select an option

Save wiesehahn/59fd9c7037213cb058187b805912c5d5 to your computer and use it in GitHub Desktop.
test algorithms and settings for noise classification in airborne laser scanning data

Lidar noise classification benchmark

Testing classify_with_ivf and classify_with_sor from lasR across heterogeneous ALS data. For each parameter combination: noise points classified (class 7), runtime, and a qualitative score out of 10.

classify_with_ipf was excluded after initial tests showed poor performance and slow runtimes.


Results

Solling 2023 — sprinkled noise on forest, large file

31.8M pts · 31.8 pts/m² · 218.8 MB · returns: 27.3M / 3.06M / 1.04M / 0.29M / 0.06M

Algorithm Time (s) Noise pts Score Notes
IVF res=5 n=10 61.9 400 8/10 Near-surface noise partially missing
IVF res=c(5,5,2) n=10 61.3 621 9/10 Good overall classification
IVF res=2 n=5 62.5 755 9/10 Good overall classification
IVF res=10 n=25 79.7 254 7/10 Some noise missing
IVF res=20 n=500 78.4 58 3/10 Misses many noise points
IVF res=2/2 + 5/10 + 10/40 78.6 570 9/10 Multi-scale IVF
SOR k=5 m=6 104.5 55419 4/10 Many false positives in understory
SOR k=5 m=8 110.7 18175 4/10 Many false positives in understory
SOR k=20 m=6 103.8 65259 4/10 Many false positives in understory
SOR k=20 m=8 90.3 17862 4/10 Many false positives in understory
SOR k=50 m=6 104.1 62783 4/10 Many false positives in understory
SOR k=50 m=8 114.1 18727 4/10 Many false positives in understory

HB 2015 — clumped + sprinkled noise, varying density due to synthetic water data

5.0M pts · 5.0 pts/m² · 22.7 MB · returns: 4.05M / 0.53M / 0.25M / 0.11M / 0.04M
Original noise: 4199 pts

Algorithm Time (s) Noise pts Score Notes
IVF res=5 n=10 6.5 376 6/10 Clumped noise missing
IVF res=c(5,5,2) n=10 6.6 1089 5/10 Clumped noise missing; FP on vertical features
IVF res=2 n=5 6.5 1196 5/10 Clumped noise missing; some FP
IVF res=10 n=25 5.9 226 5/10 Clumped + near-surface noise missing
IVF res=20 n=500 6.5 148 5/10 Near-surface missing; catches clumps somewhat better
IVF res=2/2 + 5/10 + 10/40 9.3 825 9/10 Multi-scale IVF
SOR k=5 m=6 9.6 17120 5/10 Misses some clumps; FP in low-density water regions
SOR k=5 m=8 10.6 901 5/10 Some clumped noise missing
SOR k=20 m=6 10.0 14151 5/10 Most noise caught; too many FP in water/edge regions
SOR k=20 m=8 10.2 976 6/10 Misses some clumps; FP in water/edge regions
SOR k=50 m=6 12.0 21574 5/10 Catches most noise; too many FP near water
SOR k=50 m=8 11.9 950 7/10 Catches most clumps; misses near-surface sprinkles

ST 2019 — lots of sprinkled noise, powerlines, wind turbine

12.6M pts · 12.6 pts/m² · 53.1 MB · returns: 11.65M / 0.49M / 0.26M / 0.14M / 0.06M
Original noise: 2815 pts

Algorithm Time (s) Noise pts Score Notes
IVF res=5 n=10 16.7 2475 7/10 Most noise; FP on powerlines & turbine blades
IVF res=c(5,5,2) n=10 16.4 2786 6/10 Less near-surface missing; more powerline/turbine FP
IVF res=2 n=5 17.1 3305 6/10 Less near-surface missing; more powerline/turbine FP
IVF res=10 n=25 17.1 2374 8/10 Most noise; powerlines & vertical features look good
IVF res=20 n=500 16.4 2390 7/10 Some sprinkles missing; powerlines & vertical features OK
IVF res=2/2 + 5/10 + 10/40 22.7 2735 9/10 Multi-scale IVF
SOR k=5 m=6 27.6 2734 7/10 Better near-surface; some powerline/turbine FP
SOR k=5 m=8 26.7 2608 8/10 Better near-surface; few powerline/turbine FP
SOR k=20 m=6 27.9 3089 6/10 Most noise; powerline/turbine FP
SOR k=20 m=8 28.1 2555 6/10 Near-surface sprinkles missing; powerline/turbine FP
SOR k=50 m=6 32.8 5733 5/10 Most powerlines flagged as FP
SOR k=50 m=8 32.8 3302 6/10 Some near-surface missing; powerline/turbine FP

NI 2018 — lots of sprinkled noise

5.7M pts · 5.7 pts/m² · 24.0 MB · returns: 5.15M / 0.27M / 0.15M / 0.06M / 0.01M
Original noise: 2277 pts

Algorithm Time (s) Noise pts Score Notes
IVF res=5 n=10 7.5 1741 8/10 Most noise; some near-surface missing
IVF res=c(5,5,2) n=10 7.4 2123 9/10 Minimal near-surface missing
IVF res=2 n=5 7.5 2135 9/10 Minimal near-surface missing
IVF res=10 n=25 7.5 1382 5/10 Misses much near-surface noise
IVF res=20 n=500 7.4 898 5/10 Misses much noise overall
IVF res=2/2 + 5/10 + 10/40 9.9 2035 9/10 Multi-scale IVF
SOR k=5 m=6 12.6 2175 9/10 Quite correct classification
SOR k=5 m=8 12.5 2048 9/10 Quite correct; some near-surface missing
SOR k=20 m=6 12.0 2689 7/10 Most noise; some border FP
SOR k=20 m=8 12.2 1966 9/10 Quite correct; some near-surface missing
SOR k=50 m=6 14.0 16285 5/10 Many FP in low-density regions
SOR k=50 m=8 13.9 2446 7/10 Some border FP; near-surface noise missing

NI 2016 — sparse noise

5.7M pts · 5.7 pts/m² · 21.5 MB · returns: 5.68M / 0.03M / 0.02M / 0.01M / 0.005M
Original noise: 18 pts

Algorithm Time (s) Noise pts Score Notes
IVF res=5 n=10 7.2 14 9/10 Correct classification
IVF res=c(5,5,2) n=10 7.1 36 8/10 Small FP batch at border
IVF res=2 n=5 7.2 32 8/10 Small FP batch at border
IVF res=10 n=25 7.1 14 9/10 Correct classification
IVF res=20 n=500 7.1 5 6/10 Misses some noise points
IVF res=2/2 + 5/10 + 10/40 9.9 26 9/10 Multi-scale IVF
SOR k=5 m=6 12.4 3855 5/10 Classifies noise but many FP
SOR k=5 m=8 12.4 1502 5/10 Classifies noise but many FP
SOR k=20 m=6 11.7 2000 5/10 Classifies noise but many FP
SOR k=20 m=8 11.9 610 6/10 Classifies noise but some FP
SOR k=50 m=6 13.2 1012 6/10 Classifies noise but some FP
SOR k=50 m=8 13.2 332 6/10 Classifies noise but some FP

Summary

  • IVF generally outperforms SOR across heterogeneous scenes, especially where man-made vertical structures (powerlines, wind turbines, understory) are present.
  • IVF res=c(5,5,2) n=10 and IVF res=2 n=5 consistently score highest for purely sprinkled noise (NI 2018: 9/10; Solling 2023: 9/10).
  • IVF res=10 n=25 is the best for scenes with powerlines and vertical features (ST 2019: 8/10), avoiding false positives on man-made structures.
  • Multi-scale IVF (res=2/2 + 5/10 + 10/40) provides consistent results across all tested datasets with runtime only slighly longer than single-pass IVF.
  • SOR is 1.4–1.8× slower than equivalent IVF settings and prone to large numbers of false positives in low-density regions (understory, water, tile borders).
  • SOR k=5 m=8 is the strongest SOR variant overall (ST 2019: 8/10; NI 2018: 9/10), but unreliable in dense forest.
  • IVF res=20 n=500 consistently underperforms — too conservative, misses many noise points.
  • SOR k=50 m=6 is particularly aggressive and over-classifies heavily in uniform scenes.

R code

library(lidR)
library(lasR)

reset_classes <- edit_attribute(
  filter = "Classification %between% 0 255",
  attribute = "Classification",
  value = 1
)

noise1  <- classify_with_ivf(res = 5, n = 10, class = 7)
noise2  <- classify_with_ivf(res = c(5,5,2), n = 10, class = 7)
noise3  <- classify_with_ivf(res = 2, n = 5, class = 7)
noise4  <- classify_with_ivf(res = 10, n = 25, class = 7)
noise5  <- classify_with_ivf(res = 20, n = 500, class = 7)
noise6  <- classify_with_sor(k = 5,  m = 6, class = 7)
noise7  <- classify_with_sor(k = 5,  m = 8, class = 7)
noise8  <- classify_with_sor(k = 20, m = 6, class = 7)
noise9  <- classify_with_sor(k = 20, m = 8, class = 7)
noise10 <- classify_with_sor(k = 50, m = 6, class = 7)
noise11 <- classify_with_sor(k = 50, m = 8, class = 7)

noise12 <- classify_with_ivf(res = 2, n = 2, class = 7, filter = drop_noise()) +
           classify_with_ivf(res = 5, n = 10, class = 7, filter = drop_noise()) +
           classify_with_ivf(res = 10, n = 40, class = 7, filter = drop_noise())

f <- "path/to/your.laz"

system.time({
  ans <- exec(reset_classes + noise2 + summarise() + write_las(), on = f)
})
ans$summary$npoints_per_class
readALS(ans$write_las) |>
  lidR::plot(color = "Classification", pal = c("grey", "red"), bg = "white", size = 3)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment