o
    oi                  	   @   sj   d dl Z d dlZd dlmZ d dlmZ d dlmZ ddejded	e	d
ejfddZ
G dd dejZdS )    N)nn)filter2d)create_meshgrid   ffffff?imagekernel_sizehreturnc                 C   s  t | tjstdt|  t| jdkstd| j |d dkr(tdt	t
| jd | jd t|d  }t||d| j| jd	}|t|d 8 }t|dd
d
d
d
df |dd
d
d
d
df }t||  d}t| }|  }t|}t|D ]A}	t||dd}
| t|
 }
tj|
dd}
t|
dkdd}| dkr |S |	|d  }|||
 | 7 }t|dk||}q|S )a  Approximates the Manhattan distance transform of images using cascaded convolution operations.

    The value at each pixel in the output represents the distance to the nearest non-zero pixel in the image image.
    It uses the method described in :cite:`pham2021dtlayer`.
    The transformation is applied independently across the channel dimension of the images.

    Args:
        image: Image with shape :math:`(B,C,H,W)`.
        kernel_size: size of the convolution kernel.
        h: value that influence the approximation of the min function.

    Returns:
        tensor with shape :math:`(B,C,H,W)`.

    Example:
        >>> tensor = torch.zeros(1, 1, 5, 5)
        >>> tensor[:,:, 1, 2] = 1
        >>> dt = kornia.contrib.distance_transform(tensor)

    z&image type is not a torch.Tensor. Got    z-Invalid image shape, we expect BxCxHxW. Got:    r   z"Kernel size must be an odd number.r   F)normalized_coordinatesdevicedtypeN   	replicate)border_typeg        )posinfg      ?)
isinstancetorchTensor	TypeErrortypelenshape
ValueErrormathceilmaxfloorr   r   r   hypotexp	unsqueeze
zeros_likeclone	ones_likeranger   log
nan_to_numwheresum)r   r   r	   n_itersgridkerneloutboundarysignal_onesicdtmaskoffset r5   U/home/ubuntu/.local/lib/python3.10/site-packages/kornia/contrib/distance_transform.pydistance_transform   s8   *4

r7   c                       sF   e Zd ZdZddededdf fdd	Zd
ejdejfddZ	  Z
S )DistanceTransformzModule that approximates the Manhattan (city block) distance transform of images using convolutions.

    Args:
        kernel_size: size of the convolution kernel.
        h: value that influence the approximation of the min function.

    r   r   r   r	   r
   Nc                    s   t    || _|| _d S )N)super__init__r   r	   )selfr   r	   	__class__r5   r6   r:   e   s   

zDistanceTransform.__init__r   c                 C   sF   |j d dkr|dd|j d |j d }n|}t|| j| j|S )Nr   )r   viewr7   r   r	   view_as)r;   r   image_inr5   r5   r6   forwardj   s   zDistanceTransform.forwardr   r   )__name__
__module____qualname____doc__intfloatr:   r   r   rC   __classcell__r5   r5   r<   r6   r8   \   s    r8   rD   )r   r   r   kornia.filtersr   kornia.utilsr   r   rI   rJ   r7   Moduler8   r5   r5   r5   r6   <module>   s    A