Skip to content

Commit

Permalink
Fix
Browse files Browse the repository at this point in the history
  • Loading branch information
vovaf709 committed Oct 12, 2023
1 parent 9035905 commit 14c700b
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 18 deletions.
23 changes: 16 additions & 7 deletions imops/morphology.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@

import numpy as np
from scipy.ndimage import generate_binary_structure
from skimage.morphology import binary_dilation as scipy_binary_dilation, binary_erosion as scipy_binary_erosion
from skimage.morphology import (
binary_closing as scipy_binary_closing,
binary_dilation as scipy_binary_dilation,
binary_erosion as scipy_binary_erosion,
binary_opening as scipy_binary_opening,
)

from .backend import BackendLike, Cython, Scipy, resolve_backend
from .box import add_margin, box_to_shape, mask_to_box, shape_to_box
Expand All @@ -14,7 +19,7 @@
_binary_erosion as cython_fast_binary_erosion,
)
from .src._morphology import _binary_dilation as cython_binary_dilation, _binary_erosion as cython_binary_erosion
from .utils import composition_args, morphology_composition_args, normalize_num_threads
from .utils import morphology_composition_args, normalize_num_threads


def morphology_op_wrapper(
Expand Down Expand Up @@ -42,8 +47,12 @@ def wrapped(

if output is None:
output = np.empty_like(image, dtype=bool)
elif boxed:
raise ValueError('`boxed==True` is incompatible with provided `output`')
elif output.shape != image.shape:
raise ValueError('Input image and output image shapes must be the same.')
elif output.dtype != bool:
raise ValueError(f'Output image must have `bool` dtype, got {output.dtype}.')
elif not output.data.c_contiguous:
# TODO: Implement morphology for `output` of arbitrary layout
raise ValueError('`output` must be a C-contiguous array.')
Expand All @@ -53,7 +62,7 @@ def wrapped(
if backend.name == 'Scipy':
if boxed:
raise ValueError('`boxed==True` is incompatible with "Scipy" backend.')
output = src_op(image, footprint)
src_op(image, footprint, out=output)

return output

Expand All @@ -63,7 +72,7 @@ def wrapped(
"Falling back to scipy's implementation.",
stacklevel=3,
)
output = backend2src_op[Scipy()](image, footprint)
backend2src_op[Scipy()](image, footprint, out=output)

return output

Expand Down Expand Up @@ -95,7 +104,7 @@ def wrapped(
if n_dummy:
output = output[(0,) * n_dummy]

return output.astype(bool, copy=False)
return output

return wrapped

Expand Down Expand Up @@ -244,7 +253,7 @@ def binary_erosion(
_binary_closing = morphology_op_wrapper(
'binary_closing',
{
Scipy(): composition_args(scipy_binary_erosion, scipy_binary_dilation),
Scipy(): scipy_binary_closing,
Cython(fast=False): morphology_composition_args(cython_binary_erosion, cython_binary_dilation),
Cython(fast=True): morphology_composition_args(cython_fast_binary_erosion, cython_fast_binary_dilation),
},
Expand Down Expand Up @@ -297,7 +306,7 @@ def binary_closing(
_binary_opening = morphology_op_wrapper(
'binary_opening',
{
Scipy(): composition_args(scipy_binary_dilation, scipy_binary_erosion),
Scipy(): scipy_binary_opening,
Cython(fast=False): morphology_composition_args(cython_binary_dilation, cython_binary_erosion),
Cython(fast=True): morphology_composition_args(cython_fast_binary_dilation, cython_fast_binary_erosion),
},
Expand Down
8 changes: 0 additions & 8 deletions imops/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,14 +151,6 @@ def broadcast_to_axis(axis: AxesLike, *arrays: AxesParams):
return tuple(np.repeat(x, len(axis) // len(x), 0) for x in arrays)


# TODO: come up with a better name
def composition_args(f: Callable, g: Callable) -> Callable:
def inner(*args):
return f(g(*args), *args[1:])

return inner


def morphology_composition_args(f, g) -> Callable:
def wrapper(
image: np.ndarray,
Expand Down
6 changes: 3 additions & 3 deletions tests/test_morphology.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,9 +150,9 @@ def take_by_coords(array, coords):
box_pos = np.asarray([np.random.randint(0, s - bs + 1) for bs, s in zip(box_size, shape)])
box_coord = np.array([box_pos, box_pos + box_size])
inp = np.random.binomial(1, 0.7, box_size)
inp = restore_crop(inp, box_coord, shape, 0)
inp = restore_crop(inp, box_coord, shape, 0).astype(bool)
else:
inp = np.random.binomial(1, 0.5, shape)
inp = np.random.binomial(1, 0.5, shape).astype(bool)

footprint_shape = footprint_shape_modifier(np.random.randint(1, 4, size=inp.ndim))
footprint = np.random.binomial(1, 0.5, footprint_shape) if np.random.binomial(1, 0.5) else None
Expand All @@ -175,7 +175,7 @@ def take_by_coords(array, coords):
desired_out = sk_op(inp, footprint)
output = np.empty_like(inp)

if np.random.binomial(1, 0.5):
if np.random.binomial(1, 0.5) or boxed:
output = imops_op(inp, footprint, backend=backend, boxed=boxed)
else:
imops_op(inp, footprint, output=output, backend=backend, boxed=boxed)
Expand Down

0 comments on commit 14c700b

Please sign in to comment.