Source code for cellmap_data.transforms.targets.distance

# from py_distance_transforms import transform_cuda, transform
import torch

from scipy.ndimage import distance_transform_edt as edt


[docs] def transform(x: torch.Tensor) -> torch.Tensor: return torch.tensor(edt(x.cpu().numpy())).to(x.device)
[docs] class DistanceTransform(torch.nn.Module): """ Compute the distance transform of the input. Attributes: use_cuda (bool): Use CUDA. Methods: _transform: Transform the input. forward: Forward pass. """ def __init__(self, use_cuda: bool = False) -> None: """ Initialize the distance transform. Args: use_cuda (bool, optional): Use CUDA. Defaults to False. Raises: NotImplementedError: CUDA is not supported yet. """ UserWarning("This is still in development and may not work as expected") super().__init__() self.use_cuda = use_cuda if self.use_cuda: raise NotImplementedError( "CUDA is not supported yet because testing did not return expected results." ) def _transform(self, x: torch.Tensor) -> torch.Tensor: """Transform the input.""" if self.use_cuda and x.device.type == "cuda": raise NotImplementedError( "CUDA is not supported yet because testing did not return expected results." ) # return transform_cuda(x) else: return transform(x)
[docs] def forward(self, x: torch.Tensor) -> torch.Tensor: """Forward pass.""" # TODO: Need to figure out how to prevent having inaccurate distance values at the edges --> precompute # distance = self._transform(x.nan_to_num(0)) distance = self._transform(x) distance[x.isnan()] = torch.nan x = distance return x
[docs] class SignedDistanceTransform(torch.nn.Module): """ Compute the signed distance transform of the input - positive within objects and negative outside. Attributes: use_cuda (bool): Use CUDA. Methods: _transform: Transform the input. forward: Forward pass. """ def __init__(self, use_cuda: bool = False) -> None: """ Initialize the signed distance transform. Args: use_cuda (bool, optional): Use CUDA. Defaults to False. Raises: NotImplementedError: CUDA is not supported yet. """ UserWarning("This is still in development and may not work as expected") super().__init__() self.use_cuda = use_cuda if self.use_cuda: raise NotImplementedError( "CUDA is not supported yet because testing did not return expected results." ) def _transform(self, x: torch.Tensor) -> torch.Tensor: """Transform the input.""" if self.use_cuda and x.device.type == "cuda": raise NotImplementedError( "CUDA is not supported yet because testing did not return expected results." ) # return transform_cuda(x) - transform_cuda(x.logical_not()) else: return transform(x) - transform(x.logical_not())
[docs] def forward(self, x: torch.Tensor) -> torch.Tensor: """Forward pass.""" # TODO: Need to figure out how to prevent having inaccurate distance values at the edges --> precompute # distance = self._transform(x.nan_to_num(0)) distance = self._transform(x) distance[x.isnan()] = torch.nan x = distance return x