Skip to main content

Morphological image processing for 3D multi-label images.

Project description

Automated Tests PyPI version

fastmorph: multilabel 3D morphological image processing functions.

This is a collection of morphological 3D image operations that are tuned for working with dense 3D labeled images.

We provide the following multithreaded (except where noted) operations:

  • Multi-Label Stenciled Dilation, Erosion, Opening, Closing
  • Grayscale Stenciled Dilation, Erosion, Opening, Closing
  • Multi-Label Spherical Erosion
  • Binary Spherical Dilation, Opening, and Closing
  • Multi-Label Fill Voids (single threaded)

Highlights compared to other libraries:

  • Handles multi-labeled images
  • Multithreaded
  • High performance single-threaded
  • Low memory usage
  • Dilate computes mode of surrounding labels

Disadvantages versus other libraries:

  • Stencil (structuring element) is fixed size 3x3x3 and all on.
import fastmorph

# may be binary or unsigned integer 2D or 3D image
labels = np.load("my_labels.npy")


# multi-label capable morphological operators
# they use a 3x3x3 all on structuring element
# dilate picks the mode of surrounding labels

# by default only background (0) labels are filled
morphed = fastmorph.dilate(labels, parallel=2)
# processes every voxel
morphed = fastmorph.dilate(labels, background_only=False, parallel=2)

morphed = fastmorph.erode(labels)
morphed = fastmorph.opening(labels, parallel=2)
morphed = fastmorph.closing(labels, parallel=2)

# You can select grayscale dilation, erosion, opening, and 
# closing by passing in a different Mode enum.
# The options are Mode.grey and Mode.multilabel
morphed = fastmorph.dilate(labels, mode=fastmorph.Mode.grey)
morphed = fastmorph.erode(labels, mode=fastmorph.Mode.grey)

# Dilate only supports binary images at this time.
# Radius is specified in physical units, but
# by default anisotropy = (1,1,1) so it is the 
# same as voxels.
morphed = fastmorph.spherical_dilate(labels, radius=1, parallel=2, anisotropy=(1,1,1))

# open and close require dialate to work and so are binary only for now
morphed = fastmorph.spherical_open(labels, radius=1, parallel=2, anisotropy=(1,1,1))
morphed = fastmorph.spherical_close(labels, radius=1, parallel=2, anisotropy=(1,1,1))

# The rest support multilabel images.
morphed = fastmorph.spherical_erode(labels, radius=1, parallel=2, anisotropy=(1,1,1))

# Note: for boolean images, this function will directly call fill_voids
# and return a scalar for ct 
# For integer images, more processing will be done to deal with multiple labels.
# A dict of { label: num_voxels_filled } for integer images will be returned.
# Note that for multilabel images, by default, if a label is totally enclosed by another,
# a FillError will be raised. If remove_enclosed is True, the label will be overwritten.
filled_labels, ct = fastmorph.fill_holes(labels, return_fill_count=True, remove_enclosed=False)

Performance

A test run on an M1 Macbook Pro on connectomics.npy.ckl, a 5123 volume with over 2000 dense labels had the following results for multilabel processing.

erode / 1 thread: 1.553 sec
erode / 2 threads: 0.885 sec
erode / 4 threads: 0.651 sec
dilate / background_only=True / 1 thread: 1.100 sec
dilate / background_only=True / 2 threads: 0.632 sec
dilate / background_only=True / 4 threads: 0.441 sec
dilate / background_only=False / 1 thread: 11.783 sec
dilate / background_only=False / 2 threads: 5.944 sec
dilate / background_only=False / 4 threads: 4.291 sec
dilate / background_only=False / 8 threads: 3.298 sec
scipy grey_dilation / 1 thread 14.648 sec
scipy grey_erode / 1 thread: 14.412 sec
skimage expand_labels / 1 thread: 62.248 sec

Test run on an M1 Macbook Pro with ws.npy.ckl a 5123 volume with tens of thousands of components for multilabel processing.

erode / 1 thread: 2.380 sec
erode / 2 threads: 1.479 sec
erode / 4 threads: 1.164 sec
dilate / background_only=True / 1 thread: 1.598 sec
dilate / background_only=True / 2 threads: 1.011 sec
dilate / background_only=True / 4 threads: 0.805 sec
dilate / background_only=False / 1 thread: 25.182 sec
dilate / background_only=False / 2 threads: 13.513 sec
dilate / background_only=False / 4 threads: 8.749 sec
dilate / background_only=False / 8 threads: 6.640 sec
scipy grey_dilation / 1 thread 21.109 sec
scipy grey_erode / 1 thread: 20.305 sec
skimage expand_labels / 1 thread: 63.247 sec

Here is the performance on a completely zeroed 5123 volume for multilabel processing.

erode / 1 thread: 0.462 sec
erode / 2 threads: 0.289 sec
erode / 4 threads: 0.229 sec
dilate / background_only=True / 1 thread: 2.337 sec
dilate / background_only=True / 2 threads: 1.344 sec
dilate / background_only=True / 4 threads: 1.021 sec
dilate / background_only=False / 1 thread: 2.267 sec
dilate / background_only=False / 2 threads: 1.251 sec
dilate / background_only=False / 4 threads: 0.944 sec
dilate / background_only=False / 8 threads: 0.718 sec
scipy grey_dilation / 1 thread 13.516 sec
scipy grey_erode / 1 thread: 13.326 sec
skimage expand_labels / 1 thread: 35.243 sec

Memory Profiles

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

fastmorph-1.1.0.tar.gz (25.6 kB view hashes)

Uploaded Source

Built Distributions

fastmorph-1.1.0-cp312-cp312-win_amd64.whl (116.1 kB view hashes)

Uploaded CPython 3.12 Windows x86-64

fastmorph-1.1.0-cp312-cp312-win32.whl (134.6 kB view hashes)

Uploaded CPython 3.12 Windows x86

fastmorph-1.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (174.0 kB view hashes)

Uploaded CPython 3.12 manylinux: glibc 2.17+ x86-64

fastmorph-1.1.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (171.8 kB view hashes)

Uploaded CPython 3.12 manylinux: glibc 2.17+ ARM64

fastmorph-1.1.0-cp312-cp312-macosx_11_0_arm64.whl (113.5 kB view hashes)

Uploaded CPython 3.12 macOS 11.0+ ARM64

fastmorph-1.1.0-cp312-cp312-macosx_10_9_x86_64.whl (123.4 kB view hashes)

Uploaded CPython 3.12 macOS 10.9+ x86-64

fastmorph-1.1.0-cp312-cp312-macosx_10_9_universal2.whl (219.4 kB view hashes)

Uploaded CPython 3.12 macOS 10.9+ universal2 (ARM64, x86-64)

fastmorph-1.1.0-cp311-cp311-win_amd64.whl (117.6 kB view hashes)

Uploaded CPython 3.11 Windows x86-64

fastmorph-1.1.0-cp311-cp311-win32.whl (135.5 kB view hashes)

Uploaded CPython 3.11 Windows x86

fastmorph-1.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (174.0 kB view hashes)

Uploaded CPython 3.11 manylinux: glibc 2.17+ x86-64

fastmorph-1.1.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl (208.2 kB view hashes)

Uploaded CPython 3.11 manylinux: glibc 2.17+ i686

fastmorph-1.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (172.3 kB view hashes)

Uploaded CPython 3.11 manylinux: glibc 2.17+ ARM64

fastmorph-1.1.0-cp311-cp311-macosx_11_0_arm64.whl (116.2 kB view hashes)

Uploaded CPython 3.11 macOS 11.0+ ARM64

fastmorph-1.1.0-cp311-cp311-macosx_10_9_x86_64.whl (125.9 kB view hashes)

Uploaded CPython 3.11 macOS 10.9+ x86-64

fastmorph-1.1.0-cp311-cp311-macosx_10_9_universal2.whl (224.5 kB view hashes)

Uploaded CPython 3.11 macOS 10.9+ universal2 (ARM64, x86-64)

fastmorph-1.1.0-cp310-cp310-win_amd64.whl (117.1 kB view hashes)

Uploaded CPython 3.10 Windows x86-64

fastmorph-1.1.0-cp310-cp310-win32.whl (134.3 kB view hashes)

Uploaded CPython 3.10 Windows x86

fastmorph-1.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (172.6 kB view hashes)

Uploaded CPython 3.10 manylinux: glibc 2.17+ x86-64

fastmorph-1.1.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl (206.6 kB view hashes)

Uploaded CPython 3.10 manylinux: glibc 2.17+ i686

fastmorph-1.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (171.0 kB view hashes)

Uploaded CPython 3.10 manylinux: glibc 2.17+ ARM64

fastmorph-1.1.0-cp310-cp310-macosx_11_0_arm64.whl (114.7 kB view hashes)

Uploaded CPython 3.10 macOS 11.0+ ARM64

fastmorph-1.1.0-cp310-cp310-macosx_10_9_x86_64.whl (124.4 kB view hashes)

Uploaded CPython 3.10 macOS 10.9+ x86-64

fastmorph-1.1.0-cp310-cp310-macosx_10_9_universal2.whl (221.9 kB view hashes)

Uploaded CPython 3.10 macOS 10.9+ universal2 (ARM64, x86-64)

fastmorph-1.1.0-cp39-cp39-win_amd64.whl (116.9 kB view hashes)

Uploaded CPython 3.9 Windows x86-64

fastmorph-1.1.0-cp39-cp39-win32.whl (134.6 kB view hashes)

Uploaded CPython 3.9 Windows x86

fastmorph-1.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (173.4 kB view hashes)

Uploaded CPython 3.9 manylinux: glibc 2.17+ x86-64

fastmorph-1.1.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl (206.8 kB view hashes)

Uploaded CPython 3.9 manylinux: glibc 2.17+ i686

fastmorph-1.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (171.2 kB view hashes)

Uploaded CPython 3.9 manylinux: glibc 2.17+ ARM64

fastmorph-1.1.0-cp39-cp39-macosx_11_0_arm64.whl (114.8 kB view hashes)

Uploaded CPython 3.9 macOS 11.0+ ARM64

fastmorph-1.1.0-cp39-cp39-macosx_10_9_x86_64.whl (124.6 kB view hashes)

Uploaded CPython 3.9 macOS 10.9+ x86-64

fastmorph-1.1.0-cp39-cp39-macosx_10_9_universal2.whl (222.1 kB view hashes)

Uploaded CPython 3.9 macOS 10.9+ universal2 (ARM64, x86-64)

fastmorph-1.1.0-cp38-cp38-win_amd64.whl (117.2 kB view hashes)

Uploaded CPython 3.8 Windows x86-64

fastmorph-1.1.0-cp38-cp38-win32.whl (134.4 kB view hashes)

Uploaded CPython 3.8 Windows x86

fastmorph-1.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (173.1 kB view hashes)

Uploaded CPython 3.8 manylinux: glibc 2.17+ x86-64

fastmorph-1.1.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl (206.3 kB view hashes)

Uploaded CPython 3.8 manylinux: glibc 2.17+ i686

fastmorph-1.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (170.8 kB view hashes)

Uploaded CPython 3.8 manylinux: glibc 2.17+ ARM64

fastmorph-1.1.0-cp38-cp38-macosx_11_0_universal2.whl (221.5 kB view hashes)

Uploaded CPython 3.8 macOS 11.0+ universal2 (ARM64, x86-64)

fastmorph-1.1.0-cp38-cp38-macosx_11_0_arm64.whl (114.6 kB view hashes)

Uploaded CPython 3.8 macOS 11.0+ ARM64

fastmorph-1.1.0-cp38-cp38-macosx_10_9_x86_64.whl (124.3 kB view hashes)

Uploaded CPython 3.8 macOS 10.9+ x86-64

Supported by

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