Imaging utils¶
Preprocessing¶
- dpipe.im.preprocessing.normalize(x: ndarray, mean: bool = True, std: bool = True, percentiles: Optional[Union[float, Sequence[float]]] = None, axis: Optional[Union[int, Sequence[int]]] = None, dtype=None) ndarray [source]¶
Normalize
x
’s values to make mean and std independently alongaxes
equal to 0 and 1 respectively (if specified).- Parameters
x –
mean – whether to make mean == zero
std – whether to make std == 1
percentiles – if pair (a, b) - the percentiles between which mean and/or std will be estimated if scalar (s) - same as (s, 100 - s) if None - same as (0, 100).
axis – axes along which mean and/or std will be estimated independently. If None - the statistics will be estimated globally.
dtype – the dtype of the output.
- dpipe.im.preprocessing.min_max_scale(x: ndarray, axis: Optional[Union[int, Sequence[int]]] = None) ndarray [source]¶
Scale
x
’s values so that its minimum and maximum become 0 and 1 respectively independently alongaxes
.
- dpipe.im.preprocessing.bytescale(x: ndarray) ndarray [source]¶
Scales
x
’s values so that its minimum and maximum become 0 and 255 respectively. Afterwards converts it touint8
.
- dpipe.im.preprocessing.describe_connected_components(mask: ndarray, background: int = 0, drop_background: bool = True)[source]¶
Get the connected components of
mask
as well as their labels and volumes.- Parameters
mask –
background – the label of the background. The pixels with this label will be marked as the background component (even if it is not connected).
drop_background – whether to exclude the background from the returned components’ descriptions.
- Returns
labeled_mask – array of the same shape as
mask
.labels – a list of labels from the
labeled_mask
. The background label is always 0. The labels are sorted according to their corresponding volumes.volumes – a list of corresponding labels’ volumes.
- dpipe.im.preprocessing.get_greatest_component(mask: ndarray, background: int = 0, drop_background: bool = True) ndarray [source]¶
Get the greatest connected component from
mask
. Seedescribe_connected_components
for details.
Shape operations¶
- dpipe.im.shape_ops.zoom(x: ndarray, scale_factor: Union[float, Sequence[float]], axis: Optional[Union[int, Sequence[int]]] = None, order: int = 1, fill_value: Union[float, Callable] = 0, num_threads: int = -1, backend: Optional[Union[str, Backend, Type[Backend]]] = None) ndarray [source]¶
Rescale
x
according toscale_factor
along theaxis
.Uses a fast parallelizable implementation for fp32 / fp64 inputs, ndim <= 3 and order = 1.
- Parameters
x –
scale_factor –
axis – axis along which the tensor will be scaled.
order – order of interpolation.
fill_value – value to fill past edges. If Callable (e.g.
numpy.min
) -fill_value(x)
will be used.num_threads – the number of threads to use for computation. Default = the cpu count.
backend – which backend to use.
numba
,cython
andscipy
are available,cython
is used by default.
- dpipe.im.shape_ops.zoom_to_shape(x: ndarray, shape: Union[int, Sequence[int]], axis: Optional[Union[int, Sequence[int]]] = None, order: int = 1, fill_value: Union[float, Callable] = 0, num_threads: int = -1, backend: Optional[Union[str, Backend, Type[Backend]]] = None) ndarray [source]¶
Rescale
x
to matchshape
along theaxis
.Uses a fast parallelizable implementation for fp32 / fp64 inputs, ndim <= 3 and order = 1.
- Parameters
x –
shape – final shape.
axis – axes along which the tensor will be scaled.
order – order of interpolation.
fill_value – value to fill past edges. If Callable (e.g.
numpy.min
) -fill_value(x)
will be used.num_threads – the number of threads to use for computation. Default = the cpu count.
backend – which backend to use.
numba
,cython
andscipy
are available,cython
is used by default.
- dpipe.im.shape_ops.proportional_zoom_to_shape(x: ndarray, shape: Union[int, Sequence[int]], axis: Optional[Union[int, Sequence[int]]] = None, padding_values: Union[float, Sequence[float], Callable] = 0, order: int = 1) ndarray [source]¶
Proportionally rescale
x
to fitshape
alongaxes
then pad it to that shape. :param x: :param shape: final shape. :param axis: axes along whichx
will be padded. If None - the lastlen(shape)
axes are used. :param padding_values: values to pad with. :param order: order of interpolation.
- dpipe.im.shape_ops.crop_to_shape(x: ndarray, shape: Union[int, Sequence[int]], axis: Optional[Union[int, Sequence[int]]] = None, ratio: Union[float, Sequence[float]] = 0.5) ndarray [source]¶
Crop
x
to matchshape
alongaxes
. :param x: :param shape: final shape. :param axis: axes along whichx
will be padded. If None - the lastlen(shape)
axes are used. :param ratio: the fraction of the crop that will be applied to the left,1 - ratio
will be applied to the right.
- dpipe.im.shape_ops.crop_to_box(x: ndarray, box: ndarray, axis: Optional[Union[int, Sequence[int]]] = None, padding_values: Optional[Union[float, Sequence[float]]] = None) ndarray [source]¶
Crop
x
according tobox
alongaxis
.
- dpipe.im.shape_ops.restore_crop(x: ndarray, box: ndarray, shape: Union[int, Sequence[int]], padding_values: Union[float, Sequence[float]] = 0) ndarray [source]¶
Pad
x
to matchshape
. The left padding is taken equal tobox
’s start.
- dpipe.im.shape_ops.pad(x: ndarray, padding: Union[int, Sequence[int], Sequence[Sequence[int]]], axis: Optional[Union[int, Sequence[int]]] = None, padding_values: Union[float, Sequence[float], Callable] = 0) ndarray [source]¶
Pad
x
according topadding
along theaxes
.- Parameters
x – tensor to pad.
padding – if 2D array [[start_1, stop_1], …, [start_n, stop_n]] - specifies individual padding for each axis from
axis
. The length of the array must either be equal to 1 or match the length ofaxis
. If 1D array [val_1, …, val_n] - same as [[val_1, val_1], …, [val_n, val_n]]. If scalar (val) - same as [[val, val]].padding_values – values to pad with, must be broadcastable to the resulting array. If Callable (e.g.
numpy.min
) -padding_values(x)
will be used.axis – axis along which
x
will be padded.
- dpipe.im.shape_ops.pad_to_shape(x: ndarray, shape: Union[int, Sequence[int]], axis: Optional[Union[int, Sequence[int]]] = None, padding_values: Union[float, Sequence[float], Callable] = 0, ratio: Union[float, Sequence[float]] = 0.5) ndarray [source]¶
Pad
x
to matchshape
along theaxis
.- Parameters
x –
shape – final shape.
padding_values – values to pad with. If Callable (e.g.
numpy.min
) -padding_values(x)
will be used.axis – axis along which
x
will be padded.ratio – the fraction of the padding that will be applied to the left,
1.0 - ratio
will be applied to the right. By defaultratio=0.5
, i.e. it is applied uniformly to the left and right.
- dpipe.im.shape_ops.pad_to_divisible(x: ndarray, divisor: Union[int, Sequence[int]], axis: Optional[Union[int, Sequence[int]]] = None, padding_values: Union[float, Sequence[float], Callable] = 0, ratio: Union[float, Sequence[float]] = 0.5, remainder: Union[int, Sequence[int]] = 0)[source]¶
Pad
x
to be divisible bydivisor
along theaxes
.- Parameters
x –
divisor – a value an incoming array should be divisible by.
remainder –
x
will be padded such that its shape gives the remainderremainder
when divided bydivisor
.axis – axes along which the array will be padded. If None - the last
len(divisor)
axes are used.padding_values – values to pad with. If Callable (e.g.
numpy.min
) -padding_values(x)
will be used.ratio – the fraction of the padding that will be applied to the left,
1 - ratio
will be applied to the right.
References
Data augmentation¶
Metrics¶
- dpipe.im.metrics.cross_entropy_with_logits(target: ~numpy.ndarray, logits: ~numpy.ndarray, axis: int = 1, reduce: ~typing.Optional[~typing.Callable] = <function mean>)[source]¶
A numerically stable cross entropy for numpy arrays.
target
andlogits
must have the same shape except foraxis
.- Parameters
target – integer array of shape (d1, …, di, dj, …, dn)
logits – array of shape (d1, …, di, k, dj, …, dn)
axis – the axis containing the logits for each class:
logits.shape[axis] == k
reduce – the reduction operation to be applied to the final loss. If None - no reduction will be performed.
- dpipe.im.metrics.convert_to_aggregated(metrics: ~typing.Dict[str, ~typing.Callable], aggregate_fn: ~typing.Callable = <function mean>, key_prefix: str = '', key_suffix: str = '', *args, **kwargs)[source]¶
- dpipe.im.metrics.to_aggregated(metric: ~typing.Callable, aggregate: ~typing.Callable = <function mean>, *args, **kwargs)[source]¶
Converts a
metric
that receives two values to a metric that receives two sequences and returns an aggregated value.args
andkwargs
are passed as additional arguments otaggregate
.Examples
>>> mean_dice = to_aggregated(dice_score) >>> worst_dice = to_aggregated(dice_score, aggregate=np.min)
Box¶
Functions to work with boxes: immutable numpy arrays of shape (2, n) which represent the coordinates of the upper left and lower right corners of an n-dimensional rectangle.
In slicing operations, as everywhere in Python, the left corner is inclusive, and the right one is non-inclusive.
- dpipe.im.box.make_box_(iterable) ndarray [source]¶
Returns a box, generated inplace from the
iterable
. Ifiterable
was a numpy array, will make it immutable and return.
- dpipe.im.box.returns_box(func: Callable) Callable [source]¶
Returns function, decorated so that it returns a box.
- dpipe.im.box.get_containing_box(shape: tuple) ndarray [source]¶
Returns box that contains complete array of shape
shape
.
- dpipe.im.box.broadcast_box(box: ndarray, shape: tuple, dims: tuple) ndarray [source]¶
Returns box, such that it contains
box
acrossdims
and whole array with shapeshape
across other dimensions.
- dpipe.im.box.limit_box(box, limit) ndarray [source]¶
Returns a box, maximum subset of the input
box
so that start would be non-negative and stop would be limited by thelimit
.
- dpipe.im.box.get_box_padding(box: ndarray, limit)[source]¶
- Returns padding that is necessary to get
box
from array of shapelimit
. Returns padding in numpy form, so it can be given to
numpy.pad
.
- Returns padding that is necessary to get
- dpipe.im.box.add_margin(box: ndarray, margin) ndarray [source]¶
Returns a box with size increased by the
margin
(need to be broadcastable to the box) compared to the inputbox
.
Grid splitters¶
Function for working with patches from tensors. See the Working with patches tutorial for more details.
- dpipe.im.grid.get_boxes(shape: Union[int, Sequence[int]], box_size: Union[int, Sequence[int]], stride: Union[int, Sequence[int]], axis: Optional[Union[int, Sequence[int]]] = None, valid: bool = True) Iterable[ndarray] [source]¶
Yield boxes appropriate for a tensor of shape
shape
in a convolution-like fashion.- Parameters
shape – the input tensor’s shape.
box_size –
axis – axes along which the slices will be taken.
stride – the stride (step-size) of the slice.
valid – whether boxes of size smaller than
box_size
should be left out.
References
See the Working with patches tutorial for more details.
- dpipe.im.grid.divide(x: ~numpy.ndarray, patch_size: ~typing.Union[int, ~typing.Sequence[int]], stride: ~typing.Union[int, ~typing.Sequence[int]], axis: ~typing.Optional[~typing.Union[int, ~typing.Sequence[int]]] = None, valid: bool = False, get_boxes: ~typing.Callable = <function get_boxes>) Iterable[ndarray] [source]¶
A convolution-like approach to generating patches from a tensor.
- Parameters
x –
patch_size –
axis – dimensions along which the slices will be taken.
stride – the stride (step-size) of the slice.
valid – whether patches of size smaller than
patch_size
should be left out.get_boxes – function that yields boxes, for signature see
get_boxes
References
See the Working with patches tutorial for more details.
- dpipe.im.grid.combine(patches: ~typing.Iterable[~numpy.ndarray], output_shape: ~typing.Union[int, ~typing.Sequence[int]], stride: ~typing.Union[int, ~typing.Sequence[int]], axis: ~typing.Optional[~typing.Union[int, ~typing.Sequence[int]]] = None, valid: bool = False, combiner: ~typing.Type[~dpipe.im.grid.PatchCombiner] = <class 'dpipe.im.grid.Average'>, get_boxes: ~typing.Callable = <function get_boxes>) ndarray [source]¶
Build a tensor of shape
output_shape
frompatches
obtained in a convolution-like approach with corresponding parameters. The overlapping parts are aggregated using the strategy fromcombiner
- Average by default.References
See the Working with patches tutorial for more details.
Patch¶
Tools for patch extraction and generation.
- dpipe.im.patch.sample_box_center_uniformly(shape, box_size: array, random_state: Optional[RandomState] = None)[source]¶
Returns the center of a sampled uniformly box of size
box_size
, contained in the array of shapeshape
.
- dpipe.im.patch.get_random_patch(*arrays: ~numpy.ndarray, patch_size: ~typing.Union[int, ~typing.Sequence[int]], axis: ~typing.Optional[~typing.Union[int, ~typing.Sequence[int]]] = None, distribution: ~typing.Callable = <function uniform>)[source]¶
Get a random patch of size
path_size
along theaxes
for each of thearrays
. The patch position is equal for all thearrays
.- Parameters
arrays –
patch_size –
axis –
distribution (Callable(shape)) – function that samples a random number in the range
[0, n)
for each axis. Defaults to a uniform distribution.
- dpipe.im.patch.get_random_box(shape: ~typing.Union[int, ~typing.Sequence[int]], box_shape: ~typing.Union[int, ~typing.Sequence[int]], axis: ~typing.Union[int, ~typing.Sequence[int]] = None, distribution: ~typing.Callable = <function uniform>) ndarray [source]¶
Get a random box of shape
box_shape
that fits in theshape
along the givenaxes
.
Distributions¶
Module for calculation of various statistics given a discrete or piecewise-linear distribution.
- dpipe.im.dist.weighted_sum(weights: Union[ndarray, torch.Tensor], axis: Union[int, Sequence[int]], values_range: Callable) Union[ndarray, torch.Tensor] [source]¶
Calculates a weighted sum of values returned by
values_range
with the correspondingweights
along a givenaxis
.- Parameters
weights –
axis –
values_range – takes
n
as input and returns an array ofn
values wheren = weights.shape[axis]
.
- dpipe.im.dist.expectation(distribution: ~typing.Union[~numpy.ndarray, torch.Tensor], axis: int, integral: ~typing.Callable = <function polynomial>, *args, **kwargs) Union[ndarray, torch.Tensor] [source]¶
Calculates the expectation of a function
h
given itsintegral
and adistribution
.args
andkwargs
are passed tointegral
as additional arguments.- Parameters
distribution – the distribution by which the expectation will be calculated. Must sum to 1 along the
axis
.axis – the axis along which the expectation is calculated.
integral – the definite integral of the function
h
. Seepolynomial
for an example.
Notes
This function calculates the expectation by a piecewise-linear distribution in the range \([0, N]\) where
N = distribution.shape[axis] + 1
:\[\mathbb{E}_F[h] = \int\limits_0^N h(x) dF(x) = \sum\limits_0^{N-1} \int\limits_i^{i+1} h(x) dF(x) = \sum\limits_0^{N-1} distribution_i \int\limits_i^{i+1} h(x) dx = \sum\limits_0^{N-1} distribution_i \cdot (H(i+1) - H(i)),\]where \(distribution_i\) are taken along
axis
, \(H(i) = \int\limits_0^{i} h(x) dx\) are returned byintegral
.References
- dpipe.im.dist.marginal_expectation(distribution: ~typing.Union[~numpy.ndarray, torch.Tensor], axis: ~typing.Union[int, ~typing.Sequence[int]], integrals: ~typing.Union[~typing.Callable, ~typing.Sequence[~typing.Callable]] = <function polynomial>, *args, **kwargs) list [source]¶
Computes expectations along the
axis
according tointegrals
independently.args
andkwargs
are passed tointegral
as additional arguments.
Slicing¶
Images visualization¶
- dpipe.im.visualize.slice3d(*data: ndarray, axis: int = -1, scale: int = 5, max_columns: Optional[int] = None, colorbar: bool = False, show_axes: bool = False, cmap: Union[Colormap, str] = 'gray', vlim: Optional[Union[float, Sequence[float]]] = None, titles: Optional[Sequence[Optional[str]]] = None)[source]¶
Creates an interactive plot, simultaneously showing slices along a given
axis
for all the passed images.- Parameters
data –
axis –
scale – the figure scale.
max_columns – the maximal number of figures in a row. If None - all figures will be in the same row.
colorbar – Whether to display a colorbar.
show_axes – Whether to do display grid on the image.
cmap –
vlim – used to normalize luminance data. If None - the limits are determined automatically. Must be broadcastable to (len(data), 2). See
matplotlib.pyplot.imshow
(vmin and vmax) for details.
- dpipe.im.visualize.animate3d(*data: ndarray, output_path: Union[Path, str], axis: int = -1, scale: int = 5, max_columns: Optional[int] = None, colorbar: bool = False, show_axes: bool = False, cmap: str = 'gray', vlim=(None, None), fps: int = 30, writer: str = 'imagemagick', repeat: bool = True)[source]¶
Saves an animation to
output_path
, simultaneously showing slices along a givenaxis
for all the passed images.- Parameters
data (np.ndarray) –
output_path (str) –
axis (int) –
scale (int) – the figure scale.
max_columns (int) – the maximal number of figures in a row. If None - all figures will be in the same row.
colorbar (bool) – Whether to display a colorbar. Works only if ``vlim``s are not None.
show_axes (bool) – Whether to do display grid on the image.
cmap – parameters passed to matplotlib.pyplot.imshow
vlim – parameters passed to matplotlib.pyplot.imshow
fps (int) –
writer (str) –
repeat (bool) – whether the animation should repeat when the sequence of frames is completed.
Color space conversion¶
- dpipe.im.hsv.rgb_from_hsv_data(hue, saturation, value)[source]¶
Creates image in RGB format from HSV data.
- dpipe.im.hsv.gray_image_colored_mask(gray_image, mask, hue)[source]¶
Creates gray image with colored mask. Keeps intensities intact, so dark areas on gray image will be hard to see even after colorization.
Various utils¶
- dpipe.im.utils.apply_along_axes(func: Callable, x: ndarray, axis: Union[int, Sequence[int]], *args, **kwargs)[source]¶
Apply
func
to slices fromx
taken alongaxes
.args
andkwargs
are passed as additional arguments.Notes
func
must return an array of the same shape as it received.
- dpipe.im.utils.build_slices(start: Sequence[int], stop: Optional[Sequence[int]] = None) Tuple[slice, ...] [source]¶
Returns a tuple of slices built from
start
andstop
.Examples
>>> build_slices([1, 2, 3], [4, 5, 6]) (slice(1, 4), slice(2, 5), slice(3, 6)) >>> build_slices([10, 11]) (slice(10), slice(11))
- dpipe.im.utils.composition(func: Callable, *args, **kwargs)[source]¶
Applies
func
to the output of the decorated function.args
andkwargs
are passed as additional positional and keyword arguments respectively.
- dpipe.im.utils.get_mask_volume(mask: ndarray, *spacing: Union[float, Sequence[float]], location: bool = False) float [source]¶
Calculates the
mask
volume given its spatialspacing
.- Parameters
mask –
spacing – each value represents the spacing for the corresponding axis. If float - the values are uniformly spaced along this axis. If Sequence[float] - the values are non-uniformly spaced.
location – whether to interpret the Sequence[float] in
spacing
as values’ locations or spacings. IfTrue
- the deltas are used as spacings.
Shape utils¶
- dpipe.im.shape_utils.extract_dims(array, ndim=1)[source]¶
Decrease the dimensionality of
array
by extractingndim
leading singleton dimensions.
- dpipe.im.shape_utils.prepend_dims(array, ndim=1)[source]¶
Increase the dimensionality of
array
by addingndim
leading singleton dimensions.
- dpipe.im.shape_utils.append_dims(array, ndim=1)[source]¶
Increase the dimensionality of
array
by addingndim
singleton dimensions to the end of its shape.
- dpipe.im.shape_utils.insert_dims(array, index=0, ndim=1)[source]¶
Increase the dimensionality of
array
by addingndim
singleton dimensions before the specified ``index` of its shape.
- dpipe.im.shape_utils.shape_after_convolution(shape: Union[int, Sequence[int]], kernel_size: Union[int, Sequence[int]], stride: Union[int, Sequence[int]] = 1, padding: Union[int, Sequence[int]] = 0, dilation: Union[int, Sequence[int]] = 1, valid: bool = True) tuple [source]¶
Get the shape of a tensor after applying a convolution with corresponding parameters.
- dpipe.im.shape_utils.shape_after_full_convolution(shape: Union[int, Sequence[int]], kernel_size: Union[int, Sequence[int]], axis: Optional[Union[int, Sequence[int]]] = None, stride: Union[int, Sequence[int]] = 1, padding: Union[int, Sequence[int]] = 0, dilation: Union[int, Sequence[int]] = 1, valid: bool = True) tuple [source]¶
Get the shape of a tensor after applying a convolution with corresponding parameters along the given axes. The dimensions along the remaining axes will become singleton.