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.1.0 (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.0.tar.gz (138.7 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.0-py3-none-any.whl (180.3 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for grdl_imagej-0.1.0.tar.gz
Algorithm Hash digest
SHA256 4eb8050a4ee92d68c44dcc978fd6a9705e18cdbbf3f2799ad7837113589edfd0
MD5 b079c3fd6208fd3a9b1474c7760f9cdd
BLAKE2b-256 8126e4e4f3a2182f1155fc11b755258cc5bd0403ea5e8f61d710b515eb3a8b1b

See more details on using hashes here.

Provenance

The following attestation bundles were made for grdl_imagej-0.1.0.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.0-py3-none-any.whl.

File metadata

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

File hashes

Hashes for grdl_imagej-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 93ba66d9399af2d6078f6d33c1b0579d35a9dc0b43085f4816289b8b9f4f1f49
MD5 151627c316561bd7b73d3c85eeed4160
BLAKE2b-256 e10669ee31703367e7f4b642cd5cdbd97c7fe87981dec58c24937f55d2f0e727

See more details on using hashes here.

Provenance

The following attestation bundles were made for grdl_imagej-0.1.0-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