Source code for dpipe.im.shape_ops

from typing import Callable, Union

import numpy as np
from imops.crop import crop_to_box
from imops.pad import pad, pad_to_divisible, pad_to_shape, restore_crop
from imops.zoom import zoom, zoom_to_shape

from ..itertools import extract
from .axes import AxesLike, AxesParams, broadcast_to_axis, fill_by_indices, resolve_deprecation
from .utils import build_slices

__all__ = [
    'zoom', 'zoom_to_shape', 'proportional_zoom_to_shape',
    'crop_to_shape', 'crop_to_box', 'restore_crop',
    'pad', 'pad_to_shape', 'pad_to_divisible',
]


[docs]def crop_to_shape(x: np.ndarray, shape: AxesLike, axis: AxesLike = None, ratio: AxesParams = 0.5) -> np.ndarray: """ Crop ``x`` to match ``shape`` along ``axes``. Parameters ---------- x shape final shape. axis axes along which ``x`` will be padded. If None - the last ``len(shape)`` axes are used. ratio the fraction of the crop that will be applied to the left, ``1 - ratio`` will be applied to the right. """ if not hasattr(x, 'ndim') or not hasattr(x, 'shape'): x = np.asarray(x) axis = resolve_deprecation(axis, x.ndim, shape) shape, ratio = broadcast_to_axis(axis, shape, ratio) old_shape, new_shape = np.array(x.shape), np.array(fill_by_indices(x.shape, shape, axis)) if (old_shape < new_shape).any(): raise ValueError(f'The resulting shape cannot be greater than the original one: {old_shape} vs {new_shape}') ndim = len(x.shape) ratio = fill_by_indices(np.zeros(ndim), ratio, axis) start = ((old_shape - new_shape) * ratio).astype(int) return x[build_slices(start, start + new_shape)]
[docs]def proportional_zoom_to_shape( x: np.ndarray, shape: AxesLike, axis: AxesLike = None, padding_values: Union[AxesParams, Callable] = 0, order: int = 1, ) -> np.ndarray: """ Proportionally rescale ``x`` to fit ``shape`` along ``axes`` then pad it to that shape. Parameters ---------- x shape final shape. axis axes along which ``x`` will be padded. If None - the last ``len(shape)`` axes are used. padding_values values to pad with. order order of interpolation. """ x = np.asarray(x) axis = resolve_deprecation(axis, x.ndim, shape, padding_values) scale_factor = (np.array(shape, 'float64') / extract(x.shape, axis)).min() return pad_to_shape(zoom(x, scale_factor, axis, order), shape, axis, padding_values)