Skip to content

Repository files navigation

The Devil is in the Dark Pixels: Toward Brightness Bias-Robust Denoising

Official implementation of BBRD (Brightness Bias-Robust Denoising), ECCV 2026.

Sungjun Cho, Zhuangzhuang Chen, Xiaomeng Li  ·  HKUST

TL;DR Under signal-dependent camera noise, MSE-trained denoisers reconstruct dark pixels up to 6× worse than their per-band noise floor. BBRD is a drop-in MSE replacement — GMM brightness bands + empirical per-band noise normalization + softmax Group-DRO — that fixes this with zero added parameters and zero inference cost, and is the only loss (of 13 tested) that improves every brightness band at once.


Per-band PSNR during training (NAFNet, SIDD). Same model, data, and bands — only the loss differs. MSE locks in a 1.3 dB dark/bright gap that even widens; BBRD closes it to 0.8 dB.


Why MSE fails: brightness bias

For a clean image, signal-dependent (Poisson–Gaussian) noise has variance σ²(I) = αI + β. Dark regions have small absolute noise but far lower SNR, so they are intrinsically hard. MSE training makes it worse for two compounding reasons:

  1. Signal-dependent residuals — near the noise floor E[r²] ≈ Var(n) grows with brightness.
  2. Brightness-correlated Jacobian — higher input activations yield larger ‖∂f/∂θ‖.

Both factors grow with brightness, so bright pixels dominate gradient updates and dark regions stay chronically under-optimized. This holds across 8 architectures (CNNs, Transformers, SSMs) — it is a loss-level problem, not a model-capacity one.


Left: the brightest band's Jacobian norm exceeds the darkest across all architectures (SIDD). Right: BBRD pushes the PSNR-D vs PSNR-B Pareto frontier strictly outward.


Method

BBRD corrects brightness bias in three sequential steps (removing any one breaks it):

1. Brightness bands (GMM + Gaussian soft assignment). Compute a smoothed luminance map Ī = AvgPool₇ₓ₇(gray(y)). Fit a 1-D GMM to training-set intensities and pick K by BIC (K=5 for SIDD, K=3 for PolyU), placing band edges at the valleys between components. Assign each pixel softly, φ_ik = exp(−(Ī_i − c_k)² / 2σ_g²) with σ_g = 0.05, to avoid boundary discontinuities.

2. Empirical noise normalization. Normalize per-band error by the empirical per-band noise variance — estimated once over the training set and held fixed (a data property, not a learned parameter), with no parametric noise model:

MSE_k = Σ_i φ_ik (ŷ_i − y_i)² / Σ_i φ_ik
σ²_k  = Σ_i φ_ik (x_i − y_i)² / Σ_i φ_ik          # x = noisy, y = clean
R_k   = MSE_k / σ²_k

This is the step that turns reweighting from a bias-amplifier into a bias-corrector: without it, DRO upweights the noisiest (bright) bands and worsens the gap.

3. Softmax Group-DRO. Dynamically upweight whichever band is currently worst on the noise-corrected scale:

L_BBRD = Σ_k w_k · R_k ,     w_k = softmax(η · R_k) ,     η = 5

Band assignment and DRO are training-only; the deployed model is bitwise identical to one trained with vanilla MSE. See comparison_losses.py::BBRDLoss.


Brightness band construction: input → smoothed brightness map → GMM (valleys = boundaries) → Gaussian soft weights φ_ik.


Repository structure

BBRD/
├── train_bbrd.py             # Train BBRD or any baseline loss, any backbone
├── eval_per_band.py          # PSNR-D / PSNR-B / aggregate per-band evaluation
├── comparison_losses.py      # BBRDLoss (ours) + the 13 paper baselines
├── models/                   # nafnet, residual_unet, restormer (drop-in backbones)
├── datasets_module/          # paired dataset + signal-dependent noise
├── utils/
│   ├── gmm_bands.py          # GMM + BIC brightness-band edges
│   ├── evaluation.py         # brightness-stratified per-band metrics
│   └── utils.py
├── scripts/
│   ├── precompute_gmm_edges.py
│   └── run_example.sh
├── assets/                   # paper figures
└── requirements.txt

Installation

git clone https://github.com/xmed-lab/BBRD.git   # or the mirror: https://github.com/Sungjun01/BBRD.git
cd BBRD
pip install -r requirements.txt

Tested with Python 3.12 and PyTorch ≥ 2.0 (CUDA). scikit-learn is recommended for GMM band fitting (a pure-NumPy fallback is included).

Dataset layout

DenoisingDataset expects paired clean/noisy folders per split:

datasets/SIDD_256/
├── train/{clean, noisy}/      # 'clean' or 'gt'
└── val/{clean, noisy}/

We evaluate on SIDD (smartphone, dark-skewed) and PolyU (DSLR, bright-skewed, ~18.5× bright/dark energy ratio). Download from the official sources and arrange as above. Pre-trained weights are not included.


Brightness distribution across SIDD, PolyU, and LumaSet-700.

Training

# BBRD on NAFNet / SIDD: GMM bands (BIC capped at K=5) + empirical variance + Gaussian soft DRO
CUDA_VISIBLE_DEVICES=0 python train_bbrd.py \
    --loss bbrd --backbone nafnet \
    --dataset_root datasets/SIDD_256 \
    --bbrd_gmm --bbrd_gmm_k_max 5 \
    --band_type gaussian --eta 5.0 \
    --exp_name bbrd_nafnet_sidd

# MSE baseline (identical settings — for the per-band comparison)
CUDA_VISIBLE_DEVICES=0 python train_bbrd.py \
    --loss mse --backbone nafnet \
    --dataset_root datasets/SIDD_256 --exp_name mse_nafnet_sidd
  • Backbone-agnostic: --backbone {nafnet, residual_unet, restormer}. BBRD plugs into any denoiser whose forward is model(noisy) -> denoised; the paper additionally reports DRUNet, KBNet, SCUNet, SwinIR, MambaIR, and MambaIRv2 using the same loss with no per-backbone tuning.
  • Any baseline via --loss {l1, charbonnier, huber, ssim, msssim, fft, l1_fft, focal_freq, gfl, focal, ohem, uncertainty, inv_variance}.
  • Optionally precompute GMM edges once for parallel runs: python scripts/precompute_gmm_edges.py --dataset_root datasets/SIDD_256 --k_max 5.

Evaluation

CUDA_VISIBLE_DEVICES=0 python eval_per_band.py --dataset sidd \
    --backbone nafnet \
    --checkpoint outputs/bbrd_nafnet_sidd/checkpoints/best.pt \
    --dataset_root datasets/SIDD_256 --split val

Reports PSNR-D (darkest band), PSNR-B (brightest band), aggregate PSNR/SSIM, and the full per-band breakdown. Protocol: SIDD uses [0,0.2) / [0.8,1.0]; PolyU uses [0,0.45) / [0.7,1.0].


Results

Loss comparison (NAFNet). BBRD is the only method that improves both the dark and bright bands on both datasets. Best in bold.

Method SIDD PSNR-D SIDD PSNR-B SIDD PSNR PolyU PSNR-D PolyU PSNR-B PolyU PSNR
MSE (ℓ2) 37.51 38.37 39.47 35.80 37.82 38.50
ℓ1 37.60 37.67 39.65 35.94 37.87 38.68
Charbonnier 37.48 38.66 39.65 35.99 38.18 38.79
ℓ1+FFT 37.70 38.28 39.80 36.11 38.20 38.80
Focal 37.19 38.55 39.16 35.54 37.48 38.07
OHEM 37.47 38.64 39.44 36.08 37.92 38.62
Heterosc. NLL 37.29 38.09 39.37 36.09 38.12 38.75
BBRD (ours) 37.96 38.69 40.12 36.27 38.34 39.06

(Full 13-baseline table — incl. Huber, SSIM, MS-SSIM, FFT, Focal Freq., Guided Freq. — is in the paper.)

Architecture generalization (MSE → BBRD, SIDD aggregate PSNR). Same loss, no per-backbone tuning:

NAFNet DRUNet KBNet SwinIR Restormer SCUNet MambaIR MambaIRv2
MSE 39.47 40.04 39.82 39.48 40.19 40.34 40.09 40.04
BBRD 40.12 40.46 40.41 40.23 40.72 40.54 40.26 40.52

BBRD delivers up to +0.45 dB on dark bands, +0.32 dB on bright bands, and +0.65 dB aggregate on SIDD, with the largest gains in the darkest regions.


Qualitative comparison (SIDD / PolyU). BBRD corrects dark-region residuals MSE leaves behind (green = improvement; red = regression, confined to bright areas where MSE already does well).

LumaSet-700. A synthetic benchmark of 700 patches stratified uniformly across 5 brightness quintiles, rendered under signal-dependent / Gaussian / random-variance noise at 11 severity levels. BBRD beats MSE across all noise types (largest gain +0.51 dB under signal-dependent noise), showing the fix generalizes beyond heteroscedastic noise. (To be released.)


Citation

@inproceedings{cho2026bbrd,
  title     = {The Devil is in the Dark Pixels: Toward Brightness Bias-Robust Denoising},
  author    = {Cho, Sungjun and Chen, Zhuangzhuang and Li, Xiaomeng},
  booktitle = {European Conference on Computer Vision (ECCV)},
  year      = {2026}
}

Acknowledgements

Backbone architectures build on the public implementations of NAFNet and Restormer. We thank the authors of the SIDD and PolyU datasets.

License

Released under the MIT License.

About

No description, website, or topics provided.

Resources

Stars

2 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages