Short answer

Smooth a DEM only when the noise you want to remove lives at a shorter wavelength than the landforms you want to keep, and only when your downstream product tolerates the bias smoothing introduces. Smoothing is a low-pass filter: it reduces maximum slope, flattens ruggedness, and heavily damps curvature (a second derivative). That is exactly what you want before computing curvature on noisy 1 m LiDAR, and exactly what you must avoid before measuring a scarp height, a stockpile volume, or a precise drainage network. The deciding question is always what wavelength is signal and what wavelength is noise for your specific task.

What "noise" means in a DEM

Not all unwanted detail is the same, and the right treatment differs:

  • Sensor / interpolation speckle — random per-cell jitter, common in photogrammetric and radar DEMs. High-frequency, low-amplitude.
  • Pits and spikes — isolated cells far from their neighbours, often from vegetation returns not fully removed in a LiDAR DTM, water surfaces, or interpolation failures. These are outliers, not Gaussian noise.
  • Striping / banding — periodic artifacts at the tile or scan-line pitch (SRTM, some satellite DEMs). Directional and periodic.
  • Microtopography that is real but irrelevant — tractor furrows, individual boulders, tree pits in a bare-earth model. Real ground, wrong scale for a regional structural study.

Each of these needs a different filter. A single "smooth" button applied blindly will damage one class while barely touching another.

Choosing the filter

Gaussian (the default workhorse)

A Gaussian low-pass weights neighbours by a bell curve defined by sigma. It has no ringing artifacts and a clean, scale-controlled response. The effective smoothing radius is roughly 3*sigma. In QGIS use the SAGA Gaussian Filter or Simple Filter; with GDAL you can approximate it via gdal_calc convolution or, more practically, use SAGA/GRASS. In GRASS, r.neighbors method=average size=5 weight=gauss gives a Gaussian-weighted window.

Use Gaussian for general high-frequency speckle and for preparing a DEM for curvature.

Median (edge- and outlier-friendly)

A median filter replaces each cell with the median of its window. It is excellent at killing isolated pits and spikes because a single extreme value cannot pull the median, and it preserves step edges (scarps, terrace risers) far better than a mean. Use the QGIS/SAGA Majority/Median or GRASS r.neighbors method=median. A 3x3 median removes single-cell spikes; a 5x5 starts to erode genuine small features, so keep the window as small as the noise allows.

Mean / low-pass (use sparingly)

A simple averaging kernel blurs everything, including edges, and is rarely the best tool. It is acceptable only for cosmetic visual smoothing.

Specialist filters

For striping, a directional or frequency-domain (FFT notch) filter targets the specific periodic artifact without blanket smoothing. For preserving terrain edges while removing noise, a bilateral or edge-preserving filter (available in some toolchains) smooths within homogeneous areas but stops at breaks.

Match the window to the noise, not the landform

The single most important rule: set the filter scale by the noise wavelength. If speckle is per-cell (1-2 cell wavelength) at 1 m resolution, a 3x3 or sigma=1 Gaussian removes it. If you instead pick a window sized to the landform (say a 25-cell window to "see the hill"), you destroy every feature between the cell size and the hill — including most of the geology you care about.

A useful diagnostic before committing: difference the smoothed and original DEM.

gdal_calc.py -A dem.tif -B dem_smoothed.tif --outfile=residual.tif \
  --calc="A-B"
gdaldem hillshade residual.tif residual_hs.tif

The residual should look like random texture (you removed noise). If you see coherent landforms in the residual, you over-smoothed and threw away signal — reduce the window.

Worked example: curvature on 1 m LiDAR

You want plan and profile curvature to map subtle drainage and convergence on a bare-earth 1 m LiDAR DTM, but raw curvature is pure salt-and-pepper because the second derivative amplifies every cell of noise.

  1. Diagnose the noise. Inspect with a low-altitude hillshade. Identify isolated vegetation pits versus genuine micro-channels.
  2. De-spike first. Run a 3x3 median to remove vegetation pits without blurring channel edges.
  3. Gaussian to the target scale. Apply a Gaussian with sigma ~2-3 m to suppress residual speckle while keeping channels a few metres wide. This is "smooth to the analysis scale," not "smooth to oblivion."
  4. Derive curvature from the filtered DEM (gdaldem does not do curvature; use SAGA Slope, Aspect, Curvature or GRASS r.slope.aspect).
  5. Validate by differencing and by checking that mapped channels coincide with flow accumulation from a hydrologically conditioned version of the same DEM.

Document: "curvature computed on 1 m DTM after 3x3 median + Gaussian sigma=2 m."

When NOT to smooth

  • Volumetrics and cut/fill. Smoothing redistributes mass and biases volume estimates. Compute on the raw, quality-controlled surface.
  • Scarp and bank heights. Smoothing rounds the very step you are measuring, reducing the apparent height.
  • High-precision hydrology. Channels can be displaced or merged. Use hydrological conditioning (breaching/filling) rather than generic smoothing — these solve different problems.
  • Change detection / DEM differencing. Smooth both epochs identically or not at all; inconsistent smoothing creates fake change.

Common pitfalls and why they happen

  • Smoothing to hide bad data. Smoothing masks voids and seams instead of fixing them; the underlying error is still there, just less visible. Fix voids with proper void-filling, not blur.
  • One window for everything. A window tuned for a regional study erases site-scale features and vice versa. Smoothing scale is task-specific.
  • Smoothing then measuring. Analysts smooth for a clean hillshade, then measure slope on the smoothed raster, under-reporting steepness. Keep an unsmoothed copy for measurement.
  • Forgetting NoData handling. Many mean filters treat NoData as zero, pulling edge cells toward zero elevation. Confirm the filter respects NoData (GRASS and SAGA do when configured) or expands NoData at edges instead of averaging into it.

QA checklist

  • State the filter type, window/sigma, and the noise wavelength it targets, in the layer metadata.
  • Difference smoothed against original; confirm the residual is texture, not landforms.
  • Keep an unsmoothed master DEM for any measurement (volume, height, slope at points).
  • Verify NoData and edges are handled, not averaged into.
  • Smooth all epochs identically for any comparison or change-detection work.

Bathyl perspective

We smooth deliberately and reversibly: the raw surface is always preserved, and any filtered derivative carries the filter parameters and a residual check that proves we removed noise rather than terrain. Smoothing is a means to make a specific signal legible at a specific scale, never a default cleanup pass applied because the raster looked rough.

Related reading

Sources