Skip to content

Commit

Permalink
ENH: Implement ITKWASM_BIN_SHRINK
Browse files Browse the repository at this point in the history
  • Loading branch information
thewtex committed Jan 25, 2024
1 parent 75a8473 commit 1ef265d
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 33 deletions.
61 changes: 40 additions & 21 deletions ngff_zarr/methods/_itkwasm.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,31 @@ def _itkwasm_blur_and_downsample(
return downsampled.data


def _itkwasm_chunk_bin_shrink(
image_data,
shrink_factors,
):
"""Compute the local mean and downsample on a given image chunk"""
import itkwasm
from itkwasm_downsample import downsample_bin_shrink

# chunk does not have metadata attached, values are ITK defaults
image = itkwasm.image_from_array(image_data)

# Skip this image block if it has 0 voxels
block_size = image.size
if any(block_len == 0 for block_len in block_size):
return None

downsampled = downsample_bin_shrink(image, shrink_factors=shrink_factors)
return downsampled.data


def _downsample_itkwasm_bin_shrink(
ngff_image: NgffImage, default_chunks, out_chunks, scale_factors
):
import itk
import itkwasm
from itkwasm_downsample import downsample_bin_shrink

multiscales = [
ngff_image,
Expand All @@ -62,40 +83,38 @@ def _downsample_itkwasm_bin_shrink(
# For consistency for now, do not utilize direction until there is standardized support for
# direction cosines / orientation in OME-NGFF
# block_0.attrs.pop("direction", None)
block_input = itk.image_from_array(np.ones_like(block_0))
block_input = itkwasm.image_from_array(np.ones_like(block_0))
spacing = [previous_image.scale[d] for d in spatial_dims]
block_input.SetSpacing(spacing)
block_input.spacing = spacing
origin = [previous_image.translation[d] for d in spatial_dims]
block_input.SetOrigin(origin)
filt = itk.BinShrinkImageFilter.New(block_input, shrink_factors=shrink_factors)
filt.UpdateOutputInformation()
block_output = filt.GetOutput()
scale = {_image_dims[i]: s for (i, s) in enumerate(block_output.GetSpacing())}
translation = {
_image_dims[i]: s for (i, s) in enumerate(block_output.GetOrigin())
}
dtype = block_output.dtype
block_input.origin = origin
block_output = downsample_bin_shrink(
block_input, shrink_factors, information_only=False
)
scale = {_image_dims[i]: s for (i, s) in enumerate(block_output.spacing)}
translation = {_image_dims[i]: s for (i, s) in enumerate(block_output.origin)}
dtype = block_output.data.dtype
output_chunks = list(previous_image.data.chunks)
for i, c in enumerate(output_chunks):
output_chunks[i] = [
block_output.shape[i],
block_output.data.shape[i],
] * len(c)

block_neg1 = _get_block(previous_image, -1)
# block_neg1.attrs.pop("direction", None)
block_input = itk.image_from_array(np.ones_like(block_neg1))
block_input.SetSpacing(spacing)
block_input.SetOrigin(origin)
filt = itk.BinShrinkImageFilter.New(block_input, shrink_factors=shrink_factors)
filt.UpdateOutputInformation()
block_output = filt.GetOutput()
block_input = itkwasm.image_from_array(np.ones_like(block_neg1))
block_input.spacing = spacing
block_input.origin = origin
block_output = downsample_bin_shrink(
block_input, shrink_factors, information_only=False
)
for i in range(len(output_chunks)):
output_chunks[i][-1] = block_output.shape[i]
output_chunks[i][-1] = block_output.data.shape[i]
output_chunks[i] = tuple(output_chunks[i])
output_chunks = tuple(output_chunks)

downscaled_array = map_blocks(
itk.bin_shrink_image_filter,
_itkwasm_chunk_bin_shrink,
previous_image.data,
shrink_factors=shrink_factors,
dtype=dtype,
Expand Down
5 changes: 5 additions & 0 deletions ngff_zarr/to_multiscales.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
_downsample_itk_gaussian,
)
from .methods._itkwasm import (
_downsample_itkwasm_bin_shrink,
_downsample_itkwasm_gaussian,
)
from .methods._support import _spatial_dims
Expand Down Expand Up @@ -313,6 +314,10 @@ def to_multiscales(
images = _downsample_itkwasm_gaussian(
ngff_image, default_chunks, out_chunks, scale_factors
)
elif method is Methods.ITKWASM_BIN_SHRINK:
images = _downsample_itkwasm_bin_shrink(
ngff_image, default_chunks, out_chunks, scale_factors
)
elif method is Methods.ITK_GAUSSIAN:
images = _downsample_itk_gaussian(
ngff_image, default_chunks, out_chunks, scale_factors
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ classifiers = [
]
dependencies = [
"dask[array]",
"itkwasm >= 1.0b165",
"itkwasm >= 1.0b166",
"itkwasm-downsample >= 1.1.0",
"numpy",
"platformdirs",
Expand Down
24 changes: 13 additions & 11 deletions test/test_to_ngff_zarr_itkwasm.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,19 @@

from ._data import store_new_multiscales, verify_against_baseline

# def test_bin_shrink_isotropic_scale_factors(input_images):
# dataset_name = "cthead1"
# image = input_images[dataset_name]
# baseline_name = "2_4/ITKWASM_BIN_SHRINK.zarr"
# multiscales = to_multiscales(image, [2, 4], method=Methods.ITK_BIN_SHRINK)
# # store_new_multiscales(dataset_name, baseline_name, multiscales)
# verify_against_baseline(dataset_name, baseline_name, multiscales)

# baseline_name = "auto/ITK_BIN_SHRINK.zarr"
# multiscales = to_multiscales(image, method=Methods.ITK_BIN_SHRINK)
# verify_against_baseline(dataset_name, baseline_name, multiscales)

def test_bin_shrink_isotropic_scale_factors(input_images):
dataset_name = "cthead1"
image = input_images[dataset_name]
baseline_name = "2_4/ITKWASM_BIN_SHRINK.zarr"
multiscales = to_multiscales(image, [2, 4], method=Methods.ITKWASM_BIN_SHRINK)
store_new_multiscales(dataset_name, baseline_name, multiscales)
verify_against_baseline(dataset_name, baseline_name, multiscales)

baseline_name = "auto/ITKWASM_BIN_SHRINK.zarr"
multiscales = to_multiscales(image, method=Methods.ITKWASM_BIN_SHRINK)
store_new_multiscales(dataset_name, baseline_name, multiscales)
verify_against_baseline(dataset_name, baseline_name, multiscales)


def test_gaussian_isotropic_scale_factors(input_images):
Expand Down

0 comments on commit 1ef265d

Please sign in to comment.