a
    d                     @   sd   d dl Z d dlZd dlmZ d dlmZ d dlmZ deje	e
ejdddZG d	d
 d
ejZdS )    N)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rPt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 ]}	t||dd}
| t|
 }
tj|
dd}
t|
dkdd}| dkrf q|	| 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)Znormalized_coordinatesdevicedtypeN   Z	replicate)Zborder_typeg        )Zposinfg      ?)
isinstancetorchTensor	TypeErrortypelenshape
ValueErrormathceilmaxfloorr   r   r   hypotexpZ	unsqueezeZ
zeros_likecloneZ	ones_likeranger   logZ
nan_to_numwheresum)r   r   r   Zn_itersZgridkerneloutboundaryZsignal_onesiZcdtmaskoffset r(   j/var/www/html/stable-diffusion-webui/venv/lib/python3.9/site-packages/kornia/contrib/distance_transform.pydistance_transform
   s6    *4

r*   c                       s>   e Zd ZdZd
eed fddZejejd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   c                    s   t    || _|| _d S )N)super__init__r   r   )selfr   r   	__class__r(   r)   r-   R   s    
zDistanceTransform.__init__)r   r	   c                 C   sF   |j d dkr,|dd|j d |j d }n|}t|| j| j|S )Nr   )r   viewr*   r   r   Zview_as)r.   r   Zimage_inr(   r(   r)   forwardW   s    zDistanceTransform.forward)r   r   )__name__
__module____qualname____doc__intfloatr-   r   r   r4   __classcell__r(   r(   r/   r)   r+   J   s   r+   )r   r   )r   r   Ztorch.nnnnZkornia.filtersr   Zkornia.utilsr   r   r9   r:   r*   Moduler+   r(   r(   r(   r)   <module>   s   @