Vier-Wege-Entrauschen — verrauscht / Median / Bilateral / NLM

Fügt der Eingabe synthetisches Rauschen hinzu, lässt dann drei verschiedene Entrauscher auf identischen verrauschten Kopien laufen und stapelt sie in einem 2×2-Raster zum direkten Vergleich. - **medianBlur** ist am schnellsten, ideal für Impuls- Rauschen (Staubpunkte, defekte Pixel). Verschmiert feine Texturen bei höheren Radien. - **bilateralBlur** erhält Kanten beim Glätten — guter Allzweck-Entrauscher; Standardwerte liefern ein sanftes Ergebnis. - **nonLocalMeans** ist der Gold-Standard für natürliches Foto-Rauschen: mittelt Pixel im ganzen Bild gewichtet nach Patch-Ähnlichkeit, erhält feine Texturen, die die anderen verschmieren würden. Langsamer als die anderen, aber das sauberste Ergebnis. Alle drei sind reine Pixel-Operationen — keine Erweiterungen nötig. Mit den Reglern siehst du, wie sich die drei Methoden bei gleichem Rauschpegel unterscheiden.

INPUT
INPUT — Vier-Wege-Entrauschen — verrauscht / Median / Bilateral / NLM
Four-way comparison
Four-way comparison — Vier-Wege-Entrauschen — verrauscht / Median / Bilateral / NLM
JavaScript
// Four-way denoise comparison: noisy / median / bilateral / NLM
// demo_denoise.js
//!INPUT: INPUT
//!OUTPUT: OUTPUT
//!PARAM: NOISE_AMOUNT:number=0.10,min=0.0,max=0.5
//!PARAM: MEDIAN_RADIUS:number=2,min=1,max=5
//!PARAM: BILATERAL_D:number=7,min=3,max=15
//!PARAM: BILATERAL_SC:number=0.10,min=0.01,max=0.5
//!PARAM: BILATERAL_SS:number=8,min=1,max=30
//!PARAM: NLM_SEARCH:number=7,min=3,max=15
//!PARAM: NLM_PATCH:number=3,min=1,max=5
//!PARAM: NLM_H:number=0.08,min=0.01,max=0.3
//!PARAM: LABEL_SIZE:number=22,min=10,max=64

// Take the input, add `NOISE_AMOUNT` of synthetic film grain so
// there is something to denoise, then run three different
// denoisers on identical noisy copies and stack them in a 2×2
// grid for direct visual comparison:
//
//   ┌────────────────┬────────────────┐
//   │  noisy (input) │   median       │
//   │  (control)     │   (per-channel │
//   │                │    median)     │
//   ├────────────────┼────────────────┤
//   │  bilateral     │  Non-Local     │
//   │  (edge-pres.   │  Means         │
//   │   smoothing)   │  (gold std.)   │
//   └────────────────┴────────────────┘
//
// Median is fastest, ideal for impulse noise (dust spots, dead
// pixels). Bilateral preserves edges while smoothing — good for
// general use, defaults give a soft denoise. NLM is the
// gold-standard for natural-photo Gaussian noise: it averages
// pixels across the whole image weighted by patch similarity,
// preserving fine texture that the other two would smear.

const src = Engine.loadImage(INPUT);
const W = src.width;
const H = src.height;

// Add synthetic noise to the source so all four panels start
// from the same noisy reference.
const noisy = src.clone().filmGrain(NOISE_AMOUNT);
src.free();

const bandH = LABEL_SIZE + 8;
const cellW = W;
const cellH = bandH + H;
const out = Engine.createImage(1, 1);
out.setPixel(px(0, 0), new Pixel(0.05, 0.05, 0.07, 1.0));
out.resize(cellW * 2, cellH * 2);

function panel(label, image, col, row) {
  const x0 = col * cellW;
  const y0 = row * cellH;
  out.drawText(label, x0 + 16, y0 + LABEL_SIZE - 2, {
    size: LABEL_SIZE, color: NamedColor.white,
  });
  out.blendAt(image, px(x0, y0 + bandH), 1.0, BlendMode.Over);
}

// Panel 0,0 — noisy reference
panel('1) noisy input', noisy.clone(), 0, 0);

// Panel 1,0 — median
{
  const t = noisy.clone();
  t.medianBlur(MEDIAN_RADIUS);
  panel(`2) medianBlur(${MEDIAN_RADIUS})`, t, 1, 0);
  t.free();
}

// Panel 0,1 — bilateral
{
  const t = noisy.clone();
  t.bilateralBlur(BILATERAL_D, BILATERAL_SC, BILATERAL_SS);
  panel(`3) bilateralBlur(${BILATERAL_D}, ${BILATERAL_SC}, ${BILATERAL_SS})`, t, 0, 1);
  t.free();
}

// Panel 1,1 — NLM
{
  const t = noisy.clone();
  t.nonLocalMeans(NLM_SEARCH, NLM_PATCH, NLM_H);
  panel(`4) nonLocalMeans(${NLM_SEARCH}, ${NLM_PATCH}, h=${NLM_H})`, t, 1, 1);
  t.free();
}

noisy.free();
out.save(OUTPUT);
out.free();

// © 2026 Michael Lechner · mlc OpticScript · https://mlcgo.eu · Elastic License 2.0