Source code for sdt.image.masks

# SPDX-FileCopyrightText: 2020 Lukas Schrangl <lukas.schrangl@tuwien.ac.at>
#
# SPDX-License-Identifier: BSD-3-Clause

"""Geometric binary masks for image data"""
from typing import Optional, Tuple

import numpy as np

from .utils import center


[docs]class RectMask(np.ndarray): """Boolean array representing a rectangular mask""" def __new__(cls, ext: Tuple[int, ...], shape: Optional[Tuple[int, ...]] = None) -> np.ndarray: """Parameters ---------- ext Extension (shape) of the masked rectangle shape Shape of the resulting array. If this is larger than `ext`, the mask will be centered in the array. By default, the smallest possible size is chosen. """ obj = np.ones(ext, dtype=bool) return obj if shape is None else center(obj, shape)
[docs]class CircleMask(np.ndarray): """Boolean array representing a circular mask True for all coordinates :math:`x, y` where :math:`x^2 + y^2 <= (r+e)^2`, where :math:`r` is the `radius` argument to the constructor and :math:`e` the `extra` argument. The origin (i. e. where :math:`x, y` are 0) is the center of the image. Examples -------- >>> CircleMask(2) array([[False, False, True, False, False], [False, True, True, True, False], [ True, True, True, True, True], [False, True, True, True, False], [False, False, True, False, False]], dtype=bool) >>> CircleMask(2, 0.5) array([[False, True, True, True, False], [ True, True, True, True, True], [ True, True, True, True, True], [ True, True, True, True, True], [False, True, True, True, False]], dtype=bool) """ def __new__(cls, radius: int, extra: float = 0.0, shape: Optional[Tuple[int, int]] = None) -> np.ndarray: """Parameters ---------- radius Circle radius and mask size. The shape of the created array is ``(2*radius+1, 2*radius+1)``. extra Add `extra` to the radius before determining which coordinates are inside the circle. Defaults to 0. shape Shape of the resulting array. If this is larger than the mask, it will be centered in the array. By default, the smallest possible size is chosen. """ obj = np.arange(-radius, radius+1)**2 obj = (obj[np.newaxis, :] + obj[:, np.newaxis]) <= (radius + extra)**2 return obj if shape is None else center(obj, shape)
[docs]class DiamondMask(np.ndarray): """Boolean array representing a diamond-shaped (rotated square) mask True for all coordinates :math:`x, y` where :math:`|x + y| <= r + e`, where :math:`r` is the `radius` argument to the constructor and :math:`e` the `extra` argument. The origin (i. e. where :math:`x, y` are 0) is the center of the image. Examples -------- >>> DiamondMask(2) array([[False, False, True, False, False], [False, True, True, True, False], [ True, True, True, True, True], [False, True, True, True, False], [False, False, True, False, False]]) """ def __new__(cls, radius: int, extra: float = 0.0, shape: Optional[Tuple[int, int]] = None) -> np.ndarray: """Parameters ---------- radius Diamond radius and mask size. The shape of the created array is ``(2 * radius + 1, 2 * radius + 1)``. extra Add `extra` to the radius before determining which coordinates are inside the diamond. shape Shape of the resulting array. If this is larger than the mask, it will be centered in the array. By default, the smallest possible size is chosen. """ obj = np.abs(np.arange(-radius, radius+1)) obj = (obj[:, None] + obj[None, :]) <= radius + extra return obj if shape is None else center(obj, shape)