a
    d/                     @   s  d dl mZmZ d dlZd dlmZ d dlmZmZ d dl	m
Z
 dejeejef eeej ejddd	Zdejeeej ejd
ddZdejeeej ejd
ddZejejdddZG dd dejZG dd dejZG dd dejZG dd dejZdS )    )OptionalUnionN)gaussian_blur2dspatial_gradientKORNIA_CHECK_SHAPE{Gz?sobel)inputk
grads_modesigmasreturnc                 C   s  t | g d |durft|tjs4tdt| t|jdkrV|d| dkrft	d|j t
| |}|dddddf }|dddddf }t|d dd	}t|d dd	}t|| dd	}	|| |	|	  }
|| }|
||d   }|dur||d
dddd }|S )u(  Compute the Harris cornerness function.

    Function does not do any normalization or nms. The response map is computed according the following formulation:

    .. math::
        R = max(0, det(M) - k \cdot trace(M)^2)

    where:

    .. math::
        M = \sum_{(x,y) \in W}
        \begin{bmatrix}
            I^{2}_x & I_x I_y \\
            I_x I_y & I^{2}_y \\
        \end{bmatrix}

    and :math:`k` is an empirically determined constant
    :math:`k ∈ [ 0.04 , 0.06 ]`

    Args:
        input: input image with shape :math:`(B, C, H, W)`.
        k: the Harris detector free parameter.
        grads_mode: can be ``'sobel'`` for standalone use or ``'diff'`` for use on Gaussian pyramid.
        sigmas: coefficients to be multiplied by multichannel response. Should be shape of :math:`(B)`
          It is necessary for performing non-maxima-suppression across different scale pyramid levels.
          See `vlfeat <https://github.com/vlfeat/vlfeat/blob/master/vl/covdet.c#L874>`_.

    Return:
        the response map per channel with shape :math:`(B, C, H, W)`.

    Example:
        >>> input = torch.tensor([[[
        ...    [0., 0., 0., 0., 0., 0., 0.],
        ...    [0., 1., 1., 1., 1., 1., 0.],
        ...    [0., 1., 1., 1., 1., 1., 0.],
        ...    [0., 1., 1., 1., 1., 1., 0.],
        ...    [0., 1., 1., 1., 1., 1., 0.],
        ...    [0., 1., 1., 1., 1., 1., 0.],
        ...    [0., 0., 0., 0., 0., 0., 0.],
        ... ]]])  # 1x1x7x7
        >>> # compute the response map
        harris_response(input, 0.04)
        tensor([[[[0.0012, 0.0039, 0.0020, 0.0000, 0.0020, 0.0039, 0.0012],
                  [0.0039, 0.0065, 0.0040, 0.0000, 0.0040, 0.0065, 0.0039],
                  [0.0020, 0.0040, 0.0029, 0.0000, 0.0029, 0.0040, 0.0020],
                  [0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000],
                  [0.0020, 0.0040, 0.0029, 0.0000, 0.0029, 0.0040, 0.0020],
                  [0.0039, 0.0065, 0.0040, 0.0000, 0.0040, 0.0065, 0.0039],
                  [0.0012, 0.0039, 0.0020, 0.0000, 0.0020, 0.0039, 0.0012]]]])
    BCHWN'sigmas type is not a torch.Tensor. Got    r   9Invalid sigmas shape, we expect B == input.size(0). Got:       r         ?r      )r   
isinstancetorchTensor	TypeErrortypelenshapesize
ValueErrorr   r   powview)r
   r   r   r   	gradientsdxdydx2dy2dxydet_mtrace_mscores r2   a/var/www/html/stable-diffusion-webui/venv/lib/python3.9/site-packages/kornia/feature/responses.pyharris_response
   s$    9"

r4   )r
   r   r   r   c                 C   s  t | g d t| |}|dddddf }|dddddf }t|d dd}t|d dd}t|| dd}|| ||  }	|| }
d|
t|
d d	|	     }d|
t|
d d	|	     }t||}|dur||d	d
ddd }|S )a  Compute the Shi-Tomasi cornerness function.

    Function does not do any normalization or nms. The response map is computed according the following formulation:

    .. math::
        R = min(eig(M))

    where:

    .. math::
        M = \sum_{(x,y) \in W}
        \begin{bmatrix}
            I^{2}_x & I_x I_y \\
            I_x I_y & I^{2}_y \\
        \end{bmatrix}

    Args:
        input: input image with shape :math:`(B, C, H, W)`.
        grads_mode: can be ``'sobel'`` for standalone use or ``'diff'`` for use on Gaussian pyramid.
        sigmas: coefficients to be multiplied by multichannel response. Should be shape of :math:`(B)`
          It is necessary for performing non-maxima-suppression across different scale pyramid levels.
          See `vlfeat <https://github.com/vlfeat/vlfeat/blob/master/vl/covdet.c#L874>`_.

    Return:
        the response map per channel with shape :math:`(B, C, H, W)`.

    Example:
        >>> input = torch.tensor([[[
        ...    [0., 0., 0., 0., 0., 0., 0.],
        ...    [0., 1., 1., 1., 1., 1., 0.],
        ...    [0., 1., 1., 1., 1., 1., 0.],
        ...    [0., 1., 1., 1., 1., 1., 0.],
        ...    [0., 1., 1., 1., 1., 1., 0.],
        ...    [0., 1., 1., 1., 1., 1., 0.],
        ...    [0., 0., 0., 0., 0., 0., 0.],
        ... ]]])  # 1x1x7x7
        >>> # compute the response map
        gftt_response(input)
        tensor([[[[0.0155, 0.0334, 0.0194, 0.0000, 0.0194, 0.0334, 0.0155],
                  [0.0334, 0.0575, 0.0339, 0.0000, 0.0339, 0.0575, 0.0334],
                  [0.0194, 0.0339, 0.0497, 0.0000, 0.0497, 0.0339, 0.0194],
                  [0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000],
                  [0.0194, 0.0339, 0.0497, 0.0000, 0.0497, 0.0339, 0.0194],
                  [0.0334, 0.0575, 0.0339, 0.0000, 0.0339, 0.0575, 0.0334],
                  [0.0155, 0.0334, 0.0194, 0.0000, 0.0194, 0.0334, 0.0155]]]])
    r   Nr   r   r   r   r   g      ?r   r   )	r   r   r   r   sqrtabsminr'   r(   )r
   r   r   r)   r*   r+   r,   r-   r.   r/   r0   e1e2r1   r2   r2   r3   gftt_responsea   s    2
""r:   c                 C   s   t | g d |durft|tjs4tdt| t|jdkrV|d| dkrft	d|j t
| |d}|dddddf }|dddddf }|dddddf }|| |d  }|dur||dd	ddd }|S )
a  Compute the absolute of determinant of the Hessian matrix.

    Function does not do any normalization or nms. The response map is computed according the following formulation:

    .. math::
        R = det(H)

    where:

    .. math::
        M = \sum_{(x,y) \in W}
        \begin{bmatrix}
            I_{xx} & I_{xy} \\
            I_{xy} & I_{yy} \\
        \end{bmatrix}

    Args:
        input: input image with shape :math:`(B, C, H, W)`.
        grads_mode: can be ``'sobel'`` for standalone use or ``'diff'`` for use on Gaussian pyramid.
        sigmas: coefficients to be multiplied by multichannel response. Should be shape of :math:`(B)`
          It is necessary for performing non-maxima-suppression across different scale pyramid levels.
          See `vlfeat <https://github.com/vlfeat/vlfeat/blob/master/vl/covdet.c#L874>`_.

    Return:
        the response map per channel with shape :math:`(B, C, H, W)`.

    Shape:
       - Input: :math:`(B, C, H, W)`
       - Output: :math:`(B, C, H, W)`

    Examples:
        >>> input = torch.tensor([[[
        ...    [0., 0., 0., 0., 0., 0., 0.],
        ...    [0., 1., 1., 1., 1., 1., 0.],
        ...    [0., 1., 1., 1., 1., 1., 0.],
        ...    [0., 1., 1., 1., 1., 1., 0.],
        ...    [0., 1., 1., 1., 1., 1., 0.],
        ...    [0., 1., 1., 1., 1., 1., 0.],
        ...    [0., 0., 0., 0., 0., 0., 0.],
        ... ]]])  # 1x1x7x7
        >>> # compute the response map
        hessian_response(input)
        tensor([[[[0.0155, 0.0334, 0.0194, 0.0000, 0.0194, 0.0334, 0.0155],
                  [0.0334, 0.0575, 0.0339, 0.0000, 0.0339, 0.0575, 0.0334],
                  [0.0194, 0.0339, 0.0497, 0.0000, 0.0497, 0.0339, 0.0194],
                  [0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000],
                  [0.0194, 0.0339, 0.0497, 0.0000, 0.0497, 0.0339, 0.0194],
                  [0.0334, 0.0575, 0.0339, 0.0000, 0.0339, 0.0575, 0.0334],
                  [0.0155, 0.0334, 0.0194, 0.0000, 0.0194, 0.0334, 0.0155]]]])
    r   Nr   r   r   r   r   r   r   )r   r   r   r    r!   r"   r#   r$   r%   r&   r   r'   r(   )r
   r   r   r)   Zdxxr.   Zdyyr1   r2   r2   r3   hessian_response   s    6"r;   )r
   r   c                 C   sB   t | g d | ddddddf | ddddddf  S )zCompute the Difference-of-Gaussian response.

    Args:
        input: a given the gaussian 5d tensor :math:`(B, C, D, H, W)`.

    Return:
        the response map per channel with shape :math:`(B, C, D-1, H, W)`.
    )r   r   Lr   r   Nr   r   r   )r
   r2   r2   r3   dog_response   s    	r=   c                       sR   e Zd ZdZdd fddZedddZdeje	ej ejdd	d
Z
  ZS )BlobDoGzuModule that calculates Difference-of-Gaussians blobs.

    See :func:`~kornia.feature.dog_response` for details.
    Nr   c                    s   t    d S N)super__init__self	__class__r2   r3   rB     s    
zBlobDoG.__init__c                 C   s   | j jS r@   )rF   __name__rC   r2   r2   r3   __repr__  s    zBlobDoG.__repr__r
   r   r   c                 C   s   t |S r@   )r=   rD   r
   r   r2   r2   r3   forward  s    zBlobDoG.forward)NrG   
__module____qualname____doc__rB   strrH   r   r    r   rK   __classcell__r2   r2   rE   r3   r>     s   r>   c                       s`   e Zd ZdZdeeejf dd fddZe	ddd	Z
dejeej ejd
ddZ  ZS )CornerHarrisziModule that calculates Harris corners.

    See :func:`~kornia.feature.harris_response` for details.
    r	   N)r   r   c                    s@   t    t|tu r*| dt| n| d| || _d S )Nr   )rA   rB   r"   floatZregister_bufferr   Ztensorr   )rD   r   r   rE   r2   r3   rB     s    
zCornerHarris.__init__r?   c                 C   s(   | j jd t| j d d | j d S )Nz(k=z, grads_mode=))rF   rG   rP   r   r   rC   r2   r2   r3   rH   %  s    zCornerHarris.__repr__rI   c                 C   s   t || j| j|S r@   )r4   r   r   rJ   r2   r2   r3   rK   (  s    zCornerHarris.forward)r	   )N)rG   rM   rN   rO   r   rS   r   r    rB   rP   rH   r   rK   rQ   r2   r2   rE   r3   rR     s    	rR   c                       sT   e Zd ZdZddd fddZedddZdeje	ej ejd	d
dZ
  ZS )
CornerGFTTzkModule that calculates Shi-Tomasi corners.

    See :func:`~kornia.feature.gfft_response` for details.
    r	   Nr?   c                    s   t    || _d S r@   rA   rB   r   rD   r   rE   r2   r3   rB   2  s    
zCornerGFTT.__init__c                 C   s   | j jd | j d S NrT   rU   rF   rG   r   rC   r2   r2   r3   rH   7  s    zCornerGFTT.__repr__rI   c                 C   s   t || j|S r@   )r:   r   rJ   r2   r2   r3   rK   :  s    zCornerGFTT.forward)r	   )NrL   r2   r2   rE   r3   rV   ,  s   rV   c                       sT   e Zd ZdZddd fddZedddZdeje	ej ejd	d
dZ
  ZS )BlobHessianziModule that calculates Hessian blobs.

    See :func:`~kornia.feature.hessian_response` for details.
    r	   Nr?   c                    s   t    || _d S r@   rW   rX   rE   r2   r3   rB   D  s    
zBlobHessian.__init__c                 C   s   | j jd | j d S rY   rZ   rC   r2   r2   r3   rH   I  s    zBlobHessian.__repr__rI   c                 C   s   t || j|S r@   )r;   r   rJ   r2   r2   r3   rK   L  s    zBlobHessian.forward)r	   )NrL   r2   r2   rE   r3   r[   >  s   r[   )r   r	   N)r	   N)r	   N)typingr   r   r   Ztorch.nnnnZkornia.filtersr   r   Zkornia.testingr   r    rS   rP   r4   r:   r;   r=   Moduler>   rR   rV   r[   r2   r2   r2   r3   <module>   s:      X K L