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,
Annotatedparameter 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 dependenciesrequirements.txt— regenerate withpip freeze > requirements.txtafter updatingpyproject.toml.github/workflows/publish.yml— automated PyPI publication (do not edit manually)
Releasing a New Version
- Update the
versionfield inpyproject.toml(semantic versioning:major.minor.patch) - Update
requirements.txtif dependencies changed:pip install -e ".[all,dev]" && pip freeze > requirements.txt - Commit both files
- Create a git tag:
git tag v0.2.0(matches version inpyproject.toml) - Push to GitHub:
git push && git push --tags - 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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
253b8e308c9f049bbe786c9930e555fb138e408df29a07f6d66af3c5a96bba52
|
|
| MD5 |
33b086ba8eb50cb881f5158db9305bea
|
|
| BLAKE2b-256 |
55c4f06e1d7ac583020934b78306e751e3dfa7b5fa26d5a3255086401a0a8d7f
|
Provenance
The following attestation bundles were made for grdl_imagej-0.1.1.tar.gz:
Publisher:
publish.yml on GEOINT/grdl-imagej
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
grdl_imagej-0.1.1.tar.gz -
Subject digest:
253b8e308c9f049bbe786c9930e555fb138e408df29a07f6d66af3c5a96bba52 - Sigstore transparency entry: 1393458814
- Sigstore integration time:
-
Permalink:
GEOINT/grdl-imagej@715f819d7f543a1184f60463f1c288edaadc6873 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/GEOINT
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@715f819d7f543a1184f60463f1c288edaadc6873 -
Trigger Event:
release
-
Statement type:
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
74631f659a37f4b3421a4d71e6c0326c22c18b6ee4a17da981cb94ce359b1f98
|
|
| MD5 |
4c6142804a99451835e9b12374c5481c
|
|
| BLAKE2b-256 |
6b4d67292889164ac515dbe7642efcf588a8861ceed2e3a0fbbc34f4ad0b792a
|
Provenance
The following attestation bundles were made for grdl_imagej-0.1.1-py3-none-any.whl:
Publisher:
publish.yml on GEOINT/grdl-imagej
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
grdl_imagej-0.1.1-py3-none-any.whl -
Subject digest:
74631f659a37f4b3421a4d71e6c0326c22c18b6ee4a17da981cb94ce359b1f98 - Sigstore transparency entry: 1393458821
- Sigstore integration time:
-
Permalink:
GEOINT/grdl-imagej@715f819d7f543a1184f60463f1c288edaadc6873 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/GEOINT
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@715f819d7f543a1184f60463f1c288edaadc6873 -
Trigger Event:
release
-
Statement type: