a
    dX                     @   s  d dl mZmZ d dlZd dlm  mZ g dZej	ej	dddZ
dej	ej	eej	 eee  eeeeej	d	ddZdej	ej	eej	 eee  eeeeej	d	ddZdej	ej	eej	 eee  eeeeej	d	ddZdej	ej	eej	 eee  eeeeej	d	ddZdej	ej	eej	 eee  eeeeej	d	ddZdej	ej	eej	 eee  eeeeej	d	ddZd ej	ej	eej	 eee  eeeeej	d	ddZdS )!    )ListOptionalN)dilationerosionopeningclosinggradienttop_hat
bottom_hat)kernelreturnc                 C   s8   |   \}}tj|| | j| jd} | || d||S )N)dtypedevice   )sizetorchZeyer   r   view)r   hw r   e/var/www/html/stable-diffusion-webui/venv/lib/python3.9/site-packages/kornia/morphology/morphology.py_neight2channels_like_kernel	   s    r   geodesic             @unfold)	tensorr   structuring_elementoriginborder_typeborder_valuemax_valenginer   c                 C   s  t | tjstdt|  t| jdkr>td|   t |tjs\tdt| t|jdkr|td|  |j\}}	|du r|d |	d g}|d |	|d  d |d	 ||d	  d g}
|d
kr| }d}t	j
| |
||d}|du rt|}| ||d	k< n| }| ||d	k< |dkrv|d|dd|	d}t||d d\}}t|d\}}n|dkr|  \}}}}|jdd \}}t|}t	j||| d|||d	|dd	djdd\}}|||||}ntd| d|| S )a  Return the dilated image applying the same kernel in each channel.

    .. image:: _static/img/dilation.png

    The kernel must have 2 dimensions.

    Args:
        tensor: Image with shape :math:`(B, C, H, W)`.
        kernel: Positions of non-infinite elements of a flat structuring element. Non-zero values give
            the set of neighbors of the center over which the operation is applied. Its shape is :math:`(k_x, k_y)`.
            For full structural elements use torch.ones_like(structural_element).
        structuring_element: Structuring element used for the grayscale dilation. It may be a non-flat
            structuring element.
        origin: Origin of the structuring element. Default: ``None`` and uses the center of
            the structuring element as origin (rounding towards zero).
        border_type: It determines how the image borders are handled, where ``border_value`` is the value
            when ``border_type`` is equal to ``constant``. Default: ``geodesic`` which ignores the values that are
            outside the image when applying the operation.
        border_value: Value to fill past edges of input if ``border_type`` is ``constant``.
        max_val: The value of the infinite elements in the kernel.
        engine: convolution is faster and less memory hungry, and unfold is more stable numerically

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

    .. note::
       See a working example `here <https://kornia-tutorials.readthedocs.io/en/latest/
       morphology_101.html>`__.

    Example:
        >>> tensor = torch.rand(1, 3, 5, 5)
        >>> kernel = torch.ones(3, 3)
        >>> dilated_img = dilation(tensor, kernel)
    &Input type is not a torch.Tensor. Got    'Input size must have 4 dimensions. Got 'Kernel type is not a torch.Tensor. Got    (Kernel size must have 2 dimensions. Got Nr   r   r   constantmodevaluer      )r   r   convolutionpaddingZbiasdimengine * is unknown, use 'convolution' or 'unfold')
isinstancer   Tensor	TypeErrortypelenshape
ValueErrorr4   Fpad
zeros_likecloner   maxZflipr   r   conv2dr   NotImplementedErrorZview_as)r   r   r   r   r   r    r!   r"   se_hse_wpad_eoutputneighborhood_BCHWZh_padZw_padreshape_kernelr   r   r   r      sJ    -
,



$
r   c                 C   s  t | tjstdt|  t| jdkr>td|   t |tjs\tdt| t|jdkr|td|  |j\}}	|du r|d |	d g}|d |	|d  d |d	 ||d	  d g}
|d
kr|}d}t	j
| |
||d}|du rt|}| ||d	k< n| }| ||d	k< |dkrn|d|dd|	d}t|| d\}}t|d\}}n|dkr|  \}}}}|jdd \}}t|}t	j||| d|||d	|d djdd\}}|||||}ntd| d|S )a  Return the eroded image applying the same kernel in each channel.

    .. image:: _static/img/erosion.png

    The kernel must have 2 dimensions.

    Args:
        tensor: Image with shape :math:`(B, C, H, W)`.
        kernel: Positions of non-infinite elements of a flat structuring element. Non-zero values give
            the set of neighbors of the center over which the operation is applied. Its shape is :math:`(k_x, k_y)`.
            For full structural elements use torch.ones_like(structural_element).
        structuring_element (torch.Tensor, optional): Structuring element used for the grayscale dilation.
            It may be a non-flat structuring element.
        origin: Origin of the structuring element. Default: ``None`` and uses the center of
            the structuring element as origin (rounding towards zero).
        border_type: It determines how the image borders are handled, where ``border_value`` is the value
            when ``border_type`` is equal to ``constant``. Default: ``geodesic`` which ignores the values that are
            outside the image when applying the operation.
        border_value: Value to fill past edges of input if border_type is ``constant``.
        max_val: The value of the infinite elements in the kernel.
        engine: ``convolution`` is faster and less memory hungry, and ``unfold`` is more stable numerically

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

    .. note::
       See a working example `here <https://kornia-tutorials.readthedocs.io/en/latest/
       morphology_101.html>`__.

    Example:
        >>> tensor = torch.rand(1, 3, 5, 5)
        >>> kernel = torch.ones(5, 5)
        >>> output = erosion(tensor, kernel)
    r#   r$   r%   r&   r'   r(   Nr   r   r   r)   r*   r   r-   r.   r/   r0   r1   r3   r5   r6   )r7   r   r8   r9   r:   r;   r<   r=   r4   r>   r?   r@   rA   r   minr   r   rC   r   rD   )r   r   r   r   r   r    r!   r"   rE   rF   rG   rH   rI   rJ   rK   rL   rM   rN   ZHpadZWpadrO   r   r   r   r   m   sJ    -
,



 
r   c              
   C   s   t | tjstdt|  t| jdkr>td|   t |tjs\tdt| t|jdkr|td|  t	t
| ||||||d|||||||dS )	a  Return the opened image, (that means, dilation after an erosion) applying the same kernel in each channel.

    .. image:: _static/img/opening.png

    The kernel must have 2 dimensions.

    Args:
        tensor: Image with shape :math:`(B, C, H, W)`.
        kernel: Positions of non-infinite elements of a flat structuring element. Non-zero values give
            the set of neighbors of the center over which the operation is applied. Its shape is :math:`(k_x, k_y)`.
            For full structural elements use torch.ones_like(structural_element).
        structuring_element: Structuring element used for the grayscale dilation. It may be a
            non-flat structuring element.
        origin: Origin of the structuring element. Default: ``None`` and uses the center of
            the structuring element as origin (rounding towards zero).
        border_type: It determines how the image borders are handled, where ``border_value`` is the value
            when ``border_type`` is equal to ``constant``. Default: ``geodesic`` which ignores the values that are
            outside the image when applying the operation.
        border_value: Value to fill past edges of input if ``border_type`` is ``constant``.
        max_val: The value of the infinite elements in the kernel.
        engine: convolution is faster and less memory hungry, and unfold is more stable numerically

    Returns:
       torch.Tensor: Opened image with shape :math:`(B, C, H, W)`.

    .. note::
       See a working example `here <https://kornia-tutorials.readthedocs.io/en/latest/
       morphology_101.html>`__.

    Example:
        >>> tensor = torch.rand(1, 3, 5, 5)
        >>> kernel = torch.ones(3, 3)
        >>> opened_img = opening(tensor, kernel)
    r#   r$   r%   r&   r'   r(   r   r   r   r   r    r!   r   r   r   r   r    r!   r"   )r7   r   r8   r9   r:   r;   r<   r=   r4   r   r   r   r   r   r   r   r    r!   r"   r   r   r   r      s4    -	r   c              
   C   s   t | tjstdt|  t| jdkr>td|   t |tjs\tdt| t|jdkr|td|  t	t
| ||||||d|||||||dS )	a  Return the closed image, (that means, erosion after a dilation) applying the same kernel in each channel.

    .. image:: _static/img/closing.png

    The kernel must have 2 dimensions.

    Args:
        tensor: Image with shape :math:`(B, C, H, W)`.
        kernel: Positions of non-infinite elements of a flat structuring element. Non-zero values give
            the set of neighbors of the center over which the operation is applied. Its shape is :math:`(k_x, k_y)`.
            For full structural elements use torch.ones_like(structural_element).
        structuring_element: Structuring element used for the grayscale dilation. It may be a
            non-flat structuring element.
        origin: Origin of the structuring element. Default is None and uses the center of
            the structuring element as origin (rounding towards zero).
        border_type: It determines how the image borders are handled, where ``border_value`` is the value
            when ``border_type`` is equal to ``constant``. Default: ``geodesic`` which ignores the values that are
            outside the image when applying the operation.
        border_value: Value to fill past edges of input if ``border_type`` is ``constant``.
        max_val: The value of the infinite elements in the kernel.
        engine: convolution is faster and less memory hungry, and unfold is more stable numerically

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

    .. note::
       See a working example `here <https://kornia-tutorials.readthedocs.io/en/latest/
       morphology_101.html>`__.

    Example:
        >>> tensor = torch.rand(1, 3, 5, 5)
        >>> kernel = torch.ones(3, 3)
        >>> closed_img = closing(tensor, kernel)
    r#   r$   r%   r&   r'   r(   rQ   rR   )r7   r   r8   r9   r:   r;   r<   r=   r4   r   r   rS   r   r   r   r     s4    -	r   c                 C   s0   t | |||||||dt| |||||||d S )a  Return the morphological gradient of an image.

    .. image:: _static/img/gradient.png

    That means, (dilation - erosion) applying the same kernel in each channel.
    The kernel must have 2 dimensions.

    Args:
        tensor: Image with shape :math:`(B, C, H, W)`.
        kernel: Positions of non-infinite elements of a flat structuring element. Non-zero values give
            the set of neighbors of the center over which the operation is applied. Its shape is :math:`(k_x, k_y)`.
            For full structural elements use torch.ones_like(structural_element).
        structuring_element: Structuring element used for the grayscale dilation. It may be a
            non-flat structuring element.
        origin: Origin of the structuring element. Default is None and uses the center of
            the structuring element as origin (rounding towards zero).
        border_type: It determines how the image borders are handled, where ``border_value`` is the value
            when ``border_type`` is equal to ``constant``. Default: ``geodesic`` which ignores the values that are
            outside the image when applying the operation.
        border_value: Value to fill past edges of input if ``border_type`` is ``constant``.
        max_val: The value of the infinite elements in the kernel.
        engine: convolution is faster and less memory hungry, and unfold is more stable numerically

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

    .. note::
       See a working example `here <https://kornia-tutorials.readthedocs.io/en/latest/
       morphology_101.html>`__.

    Example:
        >>> tensor = torch.rand(1, 3, 5, 5)
        >>> kernel = torch.ones(3, 3)
        >>> gradient_img = gradient(tensor, kernel)
    rR   )r   r   rS   r   r   r   r   g  s*    .	r   c                 C   s   t | tjstdt|  t| jdkr>td|   t |tjs\tdt| t|jdkr|td|  | t	| |||||||d S )a+  Return the top hat transformation of an image.

    .. image:: _static/img/top_hat.png

    That means, (image - opened_image) applying the same kernel in each channel.
    The kernel must have 2 dimensions.

    See :func:`~kornia.morphology.opening` for details.

    Args:
        tensor: Image with shape :math:`(B, C, H, W)`.
        kernel: Positions of non-infinite elements of a flat structuring element. Non-zero values give
            the set of neighbors of the center over which the operation is applied. Its shape is :math:`(k_x, k_y)`.
            For full structural elements use torch.ones_like(structural_element).
        structuring_element: Structuring element used for the grayscale dilation. It may be a
            non-flat structuring element.
        origin: Origin of the structuring element. Default: ``None`` and uses the center of
            the structuring element as origin (rounding towards zero).
        border_type: It determines how the image borders are handled, where ``border_value`` is the value
            when ``border_type`` is equal to ``constant``. Default: ``geodesic`` which ignores the values that are
            outside the image when applying the operation.
        border_value: Value to fill past edges of input if ``border_type`` is ``constant``.
        max_val: The value of the infinite elements in the kernel.
        engine: convolution is faster and less memory hungry, and unfold is more stable numerically

    Returns:
       Top hat transformed image with shape :math:`(B, C, H, W)`.

    .. note::
       See a working example `here <https://kornia-tutorials.readthedocs.io/en/latest/
       morphology_101.html>`__.

    Example:
        >>> tensor = torch.rand(1, 3, 5, 5)
        >>> kernel = torch.ones(3, 3)
        >>> top_hat_img = top_hat(tensor, kernel)
    r#   r$   r%   r&   r'   r(   rR   )
r7   r   r8   r9   r:   r;   r<   r=   r4   r   rS   r   r   r   r	     s$    0r	   c              
   C   s   t | tjstdt|  t| jdkr>td|   t |tjs\tdt| t|jdkr|td|  t	| |||||||d|  S )a7  Return the bottom hat transformation of an image.

    .. image:: _static/img/bottom_hat.png

    That means, (closed_image - image) applying the same kernel in each channel.
    The kernel must have 2 dimensions.

    See :func:`~kornia.morphology.closing` for details.

    Args:
        tensor: Image with shape :math:`(B, C, H, W)`.
        kernel: Positions of non-infinite elements of a flat structuring element. Non-zero values give
            the set of neighbors of the center over which the operation is applied. Its shape is :math:`(k_x, k_y)`.
            For full structural elements use torch.ones_like(structural_element).
        structuring_element: Structuring element used for the grayscale dilation. It may be a
            non-flat structuring element.
        origin: Origin of the structuring element. Default: ``None`` and uses the center of
            the structuring element as origin (rounding towards zero).
        border_type: It determines how the image borders are handled, where ``border_value`` is the value
            when ``border_type`` is equal to ``constant``. Default: ``geodesic`` which ignores the values that are
            outside the image when applying the operation.
        border_value: Value to fill past edges of input if ``border_type`` is ``constant``.
        max_val: The value of the infinite elements in the kernel.
        engine: convolution is faster and less memory hungry, and unfold is more stable numerically

    Returns:
       Top hat transformed image with shape :math:`(B, C, H, W)`.

    .. note::
       See a working example `here <https://kornia-tutorials.readthedocs.io/en/latest/
       morphology_101.html>`__.

    Example:
        >>> tensor = torch.rand(1, 3, 5, 5)
        >>> kernel = torch.ones(3, 3)
        >>> bottom_hat_img = bottom_hat(tensor, kernel)
    r#   r$   r%   r&   r'   r(   rR   )
r7   r   r8   r9   r:   r;   r<   r=   r4   r   rS   r   r   r   r
     s*    0
r
   )NNr   r   r   r   )NNr   r   r   r   )NNr   r   r   r   )NNr   r   r   r   )NNr   r   r   r   )NNr   r   r   r   )NNr   r   r   r   )typingr   r   r   Ztorch.nn.functionalnnZ
functionalr>   __all__r8   r   intstrfloatr   r   r   r   r   r	   r
   r   r   r   r   <module>   s   	      
a      
b      
P      
Q      
F      
K      
