Skip to main content

ImageJ/Fiji algorithm ports for the GRDL framework — 22 classic image processing algorithms as pure-NumPy reimplementations

Project description

grdl-imagej

Pure-NumPy reimplementations of 22 classic ImageJ/Fiji image processing algorithms, built as an extension of the GRDL framework.

Selected for relevance to remotely sensed imagery (PAN, MSI, HSI, SAR, thermal). Each class inherits from grdl.image_processing.base.ImageTransform, carries @processor_tags metadata for capability discovery, and declares __gpu_compatible__ for downstream GPU dispatch.

Installation

pip install grdl-imagej

Or install from source:

git clone https://github.com/geoint-org/grdl-imagej.git
cd grdl-imagej
pip install -e ".[dev]"

Dependencies

  • grdl >= 0.5.1 (base classes, versioning, Annotated parameter system, vocabulary enums)
  • numpy >= 1.20.0
  • scipy >= 1.7.0

Components (22 processors)

All processors inherit from ImageTransform and follow the same pattern: instantiate with parameters, call .apply(image). Every processor carries @processor_version and @processor_tags metadata decorators, and declares its tunable parameters via Annotated type hints with Range, Options, and Desc constraint markers from grdl.image_processing.params. This metadata enables grdl-runtime catalog discovery and grdk GUI auto-configuration.

Process > Filters

Class Description
RankFilters Median, Min, Max, Mean, Variance, Despeckle
UnsharpMask Gaussian-based sharpening
GaussianBlur Isotropic/anisotropic Gaussian smoothing
Convolver Arbitrary 2D kernel convolution

Process > Subtract Background

Class Description
RollingBallBackground Sternberg's rolling-ball background subtraction

Process > Binary

Class Description
MorphologicalFilter Erode, Dilate, Open, Close, TopHat, BlackHat, Gradient
DistanceTransform Euclidean Distance Map (EDM)
Skeletonize Zhang-Suen binary thinning

Process > Enhance Contrast

Class Description
CLAHE Contrast Limited Adaptive Histogram Equalization
GammaCorrection Power-law intensity transform
ContrastEnhancer Linear histogram stretching with saturation

Process > Find Edges

Class Description
EdgeDetector Sobel, Prewitt, Roberts, LoG, Scharr

Process > FFT

Class Description
FFTBandpassFilter Frequency-domain bandpass and stripe suppression

Process > Find Maxima

Class Description
FindMaxima Prominence-based peak/target detection

Process > Image Calculator

Class Description
ImageCalculator Pixel-wise arithmetic and logical operations

Image > Adjust > Threshold

Class Description
AutoThreshold Global thresholding (Otsu, Triangle, Huang, Li, Yen, etc.)
AutoLocalThreshold Local thresholding (Bernsen, Niblack, Sauvola, Phansalkar, etc.)

Plugins > Segmentation

Class Description
StatisticalRegionMerging SRM region-based segmentation
Watershed EDT-based watershed for splitting touching objects

Image > Stacks

Class Description
ZProjection Stack projection (max, mean, median, min, sum, std)

Analyze > Analyze Particles

Class Description
AnalyzeParticles Connected component analysis with measurements

Plugins > Anisotropic Diffusion

Class Description
AnisotropicDiffusion Perona-Malik edge-preserving smoothing

Quick Start

from grdl_imagej import CLAHE, RankFilters, UnsharpMask

# Enhance contrast
clahe = CLAHE(block_size=127, n_bins=256, max_slope=3.0)
enhanced = clahe.apply(image)

# Denoise with median filter
median = RankFilters(method='median', radius=2)
denoised = median.apply(image)

# Sharpen
usm = UnsharpMask(sigma=2.0, weight=0.6)
sharpened = usm.apply(image)

Pipeline Composition

from grdl_imagej import GammaCorrection, UnsharpMask, EdgeDetector
from grdl.image_processing import Pipeline

pipe = Pipeline([
    GammaCorrection(gamma=0.5),
    UnsharpMask(sigma=2.0, weight=0.6),
    EdgeDetector(method='sobel'),
])
result = pipe.apply(image)

Target Detection

from grdl_imagej import FFTBandpassFilter, FindMaxima

# Remove background drift and high-frequency noise
bp = FFTBandpassFilter(filter_large=40, filter_small=3)
filtered = bp.apply(image)

# Find peaks
fm = FindMaxima(prominence=50.0)
peaks = fm.apply(filtered)  # (N, 2) array of [row, col]

Segmentation

from grdl_imagej import StatisticalRegionMerging, AutoThreshold

# Region segmentation
srm = StatisticalRegionMerging(Q=25)
labels = srm.apply(image)

# Binary thresholding
thresh = AutoThreshold(method='otsu')
binary = thresh.apply(image)

Project Structure

grdl-imagej/
├── grdl_imagej/
│   ├── __init__.py              # Barrel export of all 22 components
│   ├── _taxonomy.py             # ProcessorCategory → ImageJ menu label mapping
│   ├── filters/                 # RankFilters, UnsharpMask, GaussianBlur, Convolver
│   ├── background/              # RollingBallBackground
│   ├── binary/                  # MorphologicalFilter, DistanceTransform, Skeletonize
│   ├── enhance/                 # CLAHE, GammaCorrection, ContrastEnhancer
│   ├── edges/                   # EdgeDetector
│   ├── fft/                     # FFTBandpassFilter
│   ├── find_maxima/             # FindMaxima
│   ├── math/                    # ImageCalculator
│   ├── threshold/               # AutoThreshold, AutoLocalThreshold
│   ├── segmentation/            # StatisticalRegionMerging, Watershed
│   ├── stacks/                  # ZProjection
│   ├── analyze/                 # AnalyzeParticles
│   └── noise/                   # AnisotropicDiffusion
└── tests/
    ├── conftest.py              # Shared fixtures
    ├── test_imagej.py           # Unit tests for all 22 components
    └── test_benchmarks.py       # Performance benchmarks

Testing

# Run all tests
pytest tests/ -v --benchmark-disable

# Run with coverage
pytest tests/ -v --cov=grdl_imagej --cov-report=term-missing --benchmark-disable

# Run benchmarks only
pytest tests/test_benchmarks.py --benchmark-only

Publishing to PyPI

Dependency Management

All dependencies are defined in pyproject.toml. Keep these files synchronized:

  • pyproject.toml — source of truth for versions and dependencies
  • requirements.txt — regenerate with pip freeze > requirements.txt after updating pyproject.toml
  • .github/workflows/publish.yml — automated PyPI publication (do not edit manually)

Releasing a New Version

  1. Update the version field in pyproject.toml (semantic versioning: major.minor.patch)
  2. Update requirements.txt if dependencies changed: pip install -e ".[all,dev]" && pip freeze > requirements.txt
  3. Commit both files
  4. Create a git tag: git tag v0.2.0 (matches version in pyproject.toml)
  5. Push to GitHub: git push && git push --tags
  6. Create a GitHub Release from the tag — this triggers the publish workflow automatically

The workflow:

  • Builds wheels and source distribution using python -m build
  • Publishes to PyPI with OIDC authentication (secure, no API keys)
  • Artifacts are available at pypi.org/p/grdl-imagej

See CLAUDE.md for detailed dependency management guidelines.

Attribution

ImageJ is developed by Wayne Rasband at the U.S. National Institutes of Health. ImageJ 1.x source code is in the public domain.

Fiji plugins (CLAHE, Auto Local Threshold, Statistical Region Merging, Auto Threshold, Anisotropic Diffusion) are distributed under GPL-2. This package provides independent reimplementations in NumPy, not derivative works of the GPL source, but follows the same published algorithms and cites the original authors.

License

MIT License. See LICENSE for full text.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

grdl_imagej-0.1.1.tar.gz (139.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

grdl_imagej-0.1.1-py3-none-any.whl (185.1 kB view details)

Uploaded Python 3

File details

Details for the file grdl_imagej-0.1.1.tar.gz.

File metadata

  • Download URL: grdl_imagej-0.1.1.tar.gz
  • Upload date:
  • Size: 139.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for grdl_imagej-0.1.1.tar.gz
Algorithm Hash digest
SHA256 253b8e308c9f049bbe786c9930e555fb138e408df29a07f6d66af3c5a96bba52
MD5 33b086ba8eb50cb881f5158db9305bea
BLAKE2b-256 55c4f06e1d7ac583020934b78306e751e3dfa7b5fa26d5a3255086401a0a8d7f

See more details on using hashes here.

Provenance

The following attestation bundles were made for grdl_imagej-0.1.1.tar.gz:

Publisher: publish.yml on GEOINT/grdl-imagej

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file grdl_imagej-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: grdl_imagej-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 185.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for grdl_imagej-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 74631f659a37f4b3421a4d71e6c0326c22c18b6ee4a17da981cb94ce359b1f98
MD5 4c6142804a99451835e9b12374c5481c
BLAKE2b-256 6b4d67292889164ac515dbe7642efcf588a8861ceed2e3a0fbbc34f4ad0b792a

See more details on using hashes here.

Provenance

The following attestation bundles were made for grdl_imagej-0.1.1-py3-none-any.whl:

Publisher: publish.yml on GEOINT/grdl-imagej

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page