Source code for rforge.library.processes.distance

from typing import Optional, Union

import cv2
import numpy as np
from rforge.library.containers.layer import Layer
from rforge.library.tools.data_validation import check_layer
from rforge.library.tools.exceptions import Errors


[docs] def distance( layer: Union[Layer, np.ndarray], alpha: Optional[Union[Layer, np.ndarray]] = None, thresholds: Optional[Union[list, tuple]] = None, invert: bool = False, mask_size: int = 3, as_array: bool = False, ) -> Union[np.ndarray, Layer]: """Calculate the distance field of a geographical region. Args: layer: Binary layer data. alpha: Alpha layer. Defaults to None. thresholds: Thresholds to use for image binarization. Defaults to None. invert: If True, inverts the binary layer data before processing. Defaults to False. mask_size: Size of the mask for distance calculation. Defaults to 3. as_array: If True, returns the distance field as a Numpy array. Defaults to False. Returns: Distance field layer. Raises: TypeError: If inputs are not of the accepted type. """ # Data Validation array = check_layer(layer) if alpha is not None: alpha = check_layer(alpha) print(alpha) if thresholds is not None and not ( isinstance(thresholds, (list, tuple)) and len(thresholds) == 2 and all(isinstance(item, (np.number, int, float)) for item in thresholds) and thresholds[0] < thresholds[1] ): raise TypeError( Errors.bad_input( name="thresholds", expected_type="a tuple with two numericalw" ) ) if not isinstance(invert, bool): raise TypeError(Errors.bad_input(name="invert", expected_type="a boolean")) if not (isinstance(mask_size, int) and mask_size in [3, 5]): raise TypeError(Errors.bad_input(name="mask_size", expected_type="3 or 5")) if not isinstance(as_array, bool): raise TypeError(Errors.bad_input(name="as_array", expected_type="a boolean")) if thresholds is not None: mask = np.logical_and(array >= thresholds[0], array <= thresholds[1]) if invert: array = np.where(mask, 0, 255) else: array = np.where(mask, 255, 0) result = cv2.distanceTransform(np.uint8(array), cv2.DIST_L2, mask_size) result = abs(result.max() - result) if alpha is not None: result = np.dstack([result, alpha]) return result if as_array else Layer(result)