Skip to content

Commit

Permalink
ENH: Implemennt ITKWASM_LABEL_IMAGE method
Browse files Browse the repository at this point in the history
  • Loading branch information
thewtex committed Jan 25, 2024
1 parent 1ef265d commit 199073c
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 89 deletions.
27 changes: 21 additions & 6 deletions ngff_zarr/methods/_itkwasm.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ def _itkwasm_blur_and_downsample(
image_data,
shrink_factors,
kernel_radius,
smoothing,
):
"""Blur and then downsample a given image chunk"""
import itkwasm
from itkwasm_downsample import downsample

# chunk does not have metadata attached, values are ITK defaults
image = itkwasm.image_from_array(image_data)
Expand All @@ -32,9 +32,22 @@ def _itkwasm_blur_and_downsample(
if any(block_len == 0 for block_len in block_size):
return None

downsampled = downsample(
image, shrink_factors=shrink_factors, crop_radius=kernel_radius
)
if smoothing == "gaussian":
from itkwasm_downsample import downsample

downsampled = downsample(
image, shrink_factors=shrink_factors, crop_radius=kernel_radius
)
elif smoothing == "label_image":
from itkwasm_downsample import downsample_label_image

downsampled = downsample_label_image(
image, shrink_factors=shrink_factors, crop_radius=kernel_radius
)
else:
msg = f"Unknown smoothing method: {smoothing}"
raise ValueError(msg)

return downsampled.data


Expand Down Expand Up @@ -134,8 +147,8 @@ def _downsample_itkwasm_bin_shrink(
return multiscales


def _downsample_itkwasm_gaussian(
ngff_image: NgffImage, default_chunks, out_chunks, scale_factors
def _downsample_itkwasm(
ngff_image: NgffImage, default_chunks, out_chunks, scale_factors, smoothing
):
import itkwasm
from itkwasm_downsample import downsample_bin_shrink, gaussian_kernel_radius
Expand Down Expand Up @@ -232,6 +245,7 @@ def _downsample_itkwasm_gaussian(
data,
shrink_factors=shrink_factors,
kernel_radius=kernel_radius,
smoothing=smoothing,
dtype=dtype,
depth=dict(enumerate(np.flip(kernel_radius))), # overlap is in tzyx
boundary="nearest",
Expand All @@ -248,6 +262,7 @@ def _downsample_itkwasm_gaussian(
data,
shrink_factors=shrink_factors,
kernel_radius=kernel_radius,
smoothing=smoothing,
dtype=dtype,
depth=dict(enumerate(np.flip(kernel_radius))), # overlap is in tzyx
boundary="nearest",
Expand Down
10 changes: 7 additions & 3 deletions ngff_zarr/to_multiscales.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@
_downsample_itk_gaussian,
)
from .methods._itkwasm import (
_downsample_itkwasm,
_downsample_itkwasm_bin_shrink,
_downsample_itkwasm_gaussian,
)
from .methods._support import _spatial_dims
from .multiscales import Multiscales
Expand Down Expand Up @@ -311,8 +311,12 @@ def to_multiscales(
method = Methods.DASK_IMAGE_GAUSSIAN

if method is Methods.ITKWASM_GAUSSIAN:
images = _downsample_itkwasm_gaussian(
ngff_image, default_chunks, out_chunks, scale_factors
images = _downsample_itkwasm(
ngff_image, default_chunks, out_chunks, scale_factors, "gaussian"
)
elif method is Methods.ITKWASM_LABEL_IMAGE:
images = _downsample_itkwasm(
ngff_image, default_chunks, out_chunks, scale_factors, "label_image"
)
elif method is Methods.ITKWASM_BIN_SHRINK:
images = _downsample_itkwasm_bin_shrink(
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.0b166",
"itkwasm >= 1.0b167",
"itkwasm-downsample >= 1.1.0",
"numpy",
"platformdirs",
Expand Down
21 changes: 3 additions & 18 deletions test/_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,6 @@ def input_images():
)
result = {}

# store = DirectoryStore(
# test_data_dir / "input" / "cthead1.zarr", dimension_separator="/"
# )
# image_ds = xr.open_zarr(store)
# image_da = image_ds.cthead1
image = itk.imread(test_data_dir / "input" / "cthead1.png")
image_ngff = itk_image_to_ngff_image(image)
result["cthead1"] = image_ngff
Expand All @@ -45,19 +40,9 @@ def input_images():
image_ngff = itk_image_to_ngff_image(image)
result["brain_two_components"] = image_ngff

# store = DirectoryStore(
# test_data_dir / "input" / "small_head.zarr", dimension_separator="/"
# )
# image_ds = xr.open_zarr(store)
# image_da = image_ds.small_head
# result["small_head"] = image_da

# store = DirectoryStore(
# test_data_dir / "input" / "2th_cthead1.zarr",
# )
# image_ds = xr.open_zarr(store)
# image_da = image_ds['2th_cthead1']
# result["2th_cthead1"] = image_da
image = itk.imread(test_data_dir / "input" / "2th_cthead1.png")
image_ngff = itk_image_to_ngff_image(image)
result["2th_cthead1"] = image_ngff

return result

Expand Down
102 changes: 41 additions & 61 deletions test/test_to_ngff_zarr_itkwasm.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,70 +44,50 @@ def test_gaussian_isotropic_scale_factors(input_images):
# verify_against_baseline(dataset_name, baseline_name, multiscale)


# def test_gaussian_anisotropic_scale_factors(input_images):
# dataset_name = "cthead1"
# image = input_images[dataset_name]
# scale_factors = [{"x": 2, "y": 4}, {"x": 1, "y": 2}]
# multiscale = to_multiscale(image, scale_factors, method=Methods.DASK_IMAGE_GAUSSIAN)
# baseline_name = "x2y4_x1y2/DASK_IMAGE_GAUSSIAN"
# verify_against_baseline(dataset_name, baseline_name, multiscale)

# dataset_name = "small_head"
# image = input_images[dataset_name]
# scale_factors = [
# {"x": 3, "y": 2, "z": 4},
# {"x": 2, "y": 2, "z": 2},
# {"x": 1, "y": 2, "z": 1},
# ]
# multiscale = to_multiscale(image, scale_factors, method=Methods.DASK_IMAGE_GAUSSIAN)
# baseline_name = "x3y2z4_x2y2z2_x1y2z1/DASK_IMAGE_GAUSSIAN"
# verify_against_baseline(dataset_name, baseline_name, multiscale)


# def test_label_nearest_isotropic_scale_factors(input_images):
# dataset_name = "2th_cthead1"
# image = input_images[dataset_name]
# baseline_name = "2_4/DASK_IMAGE_NEAREST"
# multiscale = to_multiscale(image, [2, 4], method=Methods.DASK_IMAGE_NEAREST)
# store_new_image(dataset_name, baseline_name, multiscale)
# verify_against_baseline(dataset_name, baseline_name, multiscale)

# dataset_name = "2th_cthead1"
# image = input_images[dataset_name]
# baseline_name = "2_3/DASK_IMAGE_NEAREST"
# multiscale = to_multiscale(image, [2, 3], method=Methods.DASK_IMAGE_NEAREST)
# store_new_image(dataset_name, baseline_name, multiscale)
# verify_against_baseline(dataset_name, baseline_name, multiscale)

def test_gaussian_anisotropic_scale_factors(input_images):
dataset_name = "cthead1"
image = input_images[dataset_name]
scale_factors = [{"x": 2, "y": 2}, {"x": 2, "y": 4}]
multiscales = to_multiscales(image, scale_factors, method=Methods.ITKWASM_GAUSSIAN)
baseline_name = "x2y2_x2y4/ITKWASM_GAUSSIAN.zarr"
store_new_multiscales(dataset_name, baseline_name, multiscales)
verify_against_baseline(dataset_name, baseline_name, multiscales)

# def test_label_nearest_anisotropic_scale_factors(input_images):
# dataset_name = "2th_cthead1"
# image = input_images[dataset_name]
# scale_factors = [{"x": 2, "y": 4}, {"x": 1, "y": 2}]
# multiscale = to_multiscale(image, scale_factors, method=Methods.DASK_IMAGE_NEAREST)
# baseline_name = "x2y4_x1y2/DASK_IMAGE_NEAREST"
# store_new_image(dataset_name, baseline_name, multiscale)
# verify_against_baseline(dataset_name, baseline_name, multiscale)
# dataset_name = "small_head"
# image = input_images[dataset_name]
# scale_factors = [
# {"x": 3, "y": 2, "z": 4},
# {"x": 2, "y": 2, "z": 2},
# {"x": 1, "y": 2, "z": 1},
# ]
# multiscale = to_multiscale(image, scale_factors, method=Methods.DASK_IMAGE_GAUSSIAN)
# baseline_name = "x3y2z4_x2y2z2_x1y2z1/DASK_IMAGE_GAUSSIAN"
# verify_against_baseline(dataset_name, baseline_name, multiscale)


# def test_label_mode_isotropic_scale_factors(input_images):
# dataset_name = "2th_cthead1"
# image = input_images[dataset_name]
# baseline_name = "2_4/DASK_IMAGE_MODE"
# multiscale = to_multiscale(image, [2, 4], method=Methods.DASK_IMAGE_MODE)
# verify_against_baseline(dataset_name, baseline_name, multiscale)
def test_label_image_isotropic_scale_factors(input_images):
dataset_name = "2th_cthead1"
image = input_images[dataset_name]
baseline_name = "2_4/ITKWASM_LABEL_IMAGE.zarr"
multiscales = to_multiscales(image, [2, 4], method=Methods.ITKWASM_LABEL_IMAGE)
store_new_multiscales(dataset_name, baseline_name, multiscales)
verify_against_baseline(dataset_name, baseline_name, multiscales)

# dataset_name = "2th_cthead1"
# image = input_images[dataset_name]
# baseline_name = "2_3/DASK_IMAGE_MODE"
# multiscale = to_multiscale(image, [2, 3], method=Methods.DASK_IMAGE_MODE)
# verify_against_baseline(dataset_name, baseline_name, multiscale)
dataset_name = "2th_cthead1"
image = input_images[dataset_name]
baseline_name = "2_3/ITKWASM_LABEL_IMAGE.zarr"
multiscales = to_multiscales(image, [2, 3], method=Methods.ITKWASM_LABEL_IMAGE)
store_new_multiscales(dataset_name, baseline_name, multiscales)
verify_against_baseline(dataset_name, baseline_name, multiscales)


# def test_label_mode_anisotropic_scale_factors(input_images):
# dataset_name = "2th_cthead1"
# image = input_images[dataset_name]
# scale_factors = [{"x": 2, "y": 4}, {"x": 1, "y": 2}]
# multiscale = to_multiscale(image, scale_factors, method=Methods.DASK_IMAGE_MODE)
# baseline_name = "x2y4_x1y2/DASK_IMAGE_MODE"
# verify_against_baseline(dataset_name, baseline_name, multiscale)
def test_label_image_anisotropic_scale_factors(input_images):
dataset_name = "2th_cthead1"
image = input_images[dataset_name]
scale_factors = [{"x": 2, "y": 2}, {"x": 2, "y": 4}]
multiscales = to_multiscales(
image, scale_factors, method=Methods.ITKWASM_LABEL_IMAGE
)
baseline_name = "x2y4_x2y8/ITKWASM_LABEL_IMAGE.zarr"
store_new_multiscales(dataset_name, baseline_name, multiscales)
verify_against_baseline(dataset_name, baseline_name, multiscales)

0 comments on commit 199073c

Please sign in to comment.