Skip to content

ornlneutronimaging/bm3dornl

Build Status OpenSSF Best Practices Documentation Status PyPI Crates.io DOI

BM3D ORNL

A high-performance BM3D denoising library for neutron imaging, optimized for streak/ring artifact removal from sinograms.

The BM3D algorithm was originally proposed by K. Dabov, A. Foi, V. Katkovnik, and K. Egiazarian in the paper "Image Denoising by Sparse 3D Transform-Domain Collaborative Filtering" (2007).

BM3D ORNL provides a Python API with a Rust backend for efficient, parallel processing of tomography data. Key features:

  • Streak/Ring Artifact Removal: Specialized mode for removing vertical streak artifacts common in neutron and X-ray imaging
  • Multi-Scale Processing: True multi-scale BM3D for handling wide streaks that single-scale cannot capture (based on Mäkinen et al. 2021)
  • Fourier-SVD Method: Alternative fast algorithm (~2.6x faster than BM3D) combining FFT-based energy detection with rank-1 SVD
  • Stack Processing: Efficient batched processing of 3D sinogram stacks
  • High Performance: Rust backend with optimized block matching (integral images, early termination) and transforms (Hadamard, FFT)

How to install

Using Pip

# Core library only
pip install bm3dornl

# With GUI application
pip install bm3dornl[gui]

Supported Platforms

Platform Architecture Library GUI
Linux x86_64
macOS ARM64 (Apple Silicon)

Using Pixi (Development)

pixi install
pixi run build

Usage

from bm3dornl import bm3d_ring_artifact_removal
import numpy as np

# Load sinogram data - 2D (H, W) or 3D stack (N, H, W)
sinogram = np.load("sinogram.npy")

# Standard BM3D denoising (generic white noise)
denoised = bm3d_ring_artifact_removal(sinogram, mode="generic", sigma_random=0.1)

# Streak artifact removal (recommended for ring artifacts)
denoised = bm3d_ring_artifact_removal(sinogram, mode="streak", sigma_random=0.1)

# With custom parameters (all parameters are flat, no dict wrapping)
denoised = bm3d_ring_artifact_removal(
    sinogram,
    mode="streak",
    sigma_random=0.1,
    patch_size=8,           # Patch size (7 or 8 recommended)
    step_size=4,            # Step size for patch extraction
    search_window=40,       # Max search distance
    max_matches=64,         # Similar patches per 3D group
    batch_size=32,          # Batch size for stack processing
)

# Multi-scale BM3D for wide streaks (v0.7.0+)
denoised = bm3d_ring_artifact_removal(
    sinogram,
    mode="streak",
    multiscale=True,        # Enable multi-scale pyramid processing
    num_scales=None,        # Auto-detect (or set explicitly)
    filter_strength=1.0,    # Filtering intensity multiplier
)

Fourier-SVD Method (v0.7.0+)

For faster processing with excellent results on many datasets:

from bm3dornl.fourier_svd import fourier_svd_removal

# Fast streak removal (~2.6x faster than BM3D)
denoised = fourier_svd_removal(
    sinogram,
    fft_alpha=1.0,          # FFT-guided trust factor (0.0 disables FFT guidance)
    notch_width=2.0,        # Gaussian notch filter width
)

Performance

The Rust backend provides high performance for tomography stacks:

Metric Value
Speed ~0.63s per frame (512×512) on Apple Silicon
Memory >50% reduction via chunked processing
Parallelism Zero-overhead parallel processing via Rayon

Key optimizations:

  • Integral image pre-screening for fast block matching
  • Early termination in distance calculations
  • Pre-computed FFT plans
  • Fast Walsh-Hadamard transform for 8×8 patches

Development

We use pixi for development environment management.

  1. Clone repo.
  2. Run pixi run build to compile the Rust backend and install in editable mode.
  3. Run pixi run test to run tests.
  4. Run pixi run bench to run performance benchmarks.
git clone https://github.com/ornlneutronimaging/bm3dornl.git
cd bm3dornl
pixi run build
pixi run test

GUI Application

BM3DORNL includes a standalone GUI application for interactive ring artifact removal.

Installation

pip install bm3dornl[gui]

Or install the GUI separately:

pip install bm3dornl-gui

Launching

bm3dornl-gui

Features

  • Load HDF5 files with tree browser for dataset selection
  • Interactive slice viewer with histogram
  • Side-by-side comparison of original and processed images
  • Real-time parameter adjustment
  • ROI selection for histogram (Shift+drag to select region)
  • Export processed data to TIFF or HDF5

Keyboard Shortcuts

Shortcut Action
Shift+Drag Select ROI for histogram
Scroll Zoom in/out on image
Drag Pan image

Parameter Reference

Parameter Default Description
mode "streak" "generic" for white noise, "streak" for ring artifacts
sigma_random 0.1 Noise standard deviation
patch_size 8 Patch size (7 or 8 recommended)
step_size 3 Step size for patch extraction
search_window 39 Maximum search distance for similar patches
max_matches 16 Maximum similar patches per 3D group
batch_size 32 Batch size for stack processing
streak_sigma_smooth 1.0 Smoothing for streak mode (streak mode only)
multiscale False Enable multi-scale processing for wide streaks
num_scales None Number of scales (auto-detected if None)
filter_strength 1.0 Filtering strength multiplier for multi-scale
debin_iterations 30 Debinning iterations for multi-scale

Fourier-SVD Parameters

Parameter Default Description
fft_alpha 1.0 FFT-guided trust factor (0.0 disables FFT guidance)
notch_width 2.0 Gaussian notch filter width in frequency domain

About

Rust-based bm3d algorithm for ring artifact removal in normalized sinogram with Python Bindings

Topics

Resources

License

Code of conduct

Contributing

Stars

Watchers

Forks

Packages

No packages published

Contributors 7