o
    oi8                     @   sJ  d dl mZmZ d dlZd dlmZmZmZ d dlm	Z	 d dl
mZmZ dedefdd	Z	d(dedeeef dedee def
ddZd)dededee defddZd)dededee defddZdedefddZd*dedededefddZG dd deZG d d! d!eZG d"d# d#eZG d$d% d%eZG d&d' d'eZdS )+    )OptionalUnionN)ModuleTensortensorKORNIA_CHECK_SHAPE)gaussian_blur2dspatial_gradientsigmareturnc                 C   s(   t d|  d }|d dkr|d7 }|S )Ng       @      ?   r      )int)r   ksize r   L/home/ubuntu/.local/lib/python3.10/site-packages/kornia/feature/responses.py_get_kernel_size   s   r   {Gz?sobelinputk
grads_modesigmasc                 C   s  t | g d |dur2t|tstdt| t|jdkr*|d| dkr2t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 )uY  Compute the Harris cornerness function.

    .. image:: _static/img/harris_response.png

    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 Tensor. Got r   r   9Invalid sigmas shape, we expect B == input.size(0). Got: r      r#   r   r      )r   
isinstancer   	TypeErrortypelenshapesize
ValueErrorr
   r	   powview)r   r   r   r   	gradientsdxdydx2dy2dxydet_mtrace_mscoresr   r   r   harris_response'   s$   9
"
r9   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.

    .. image:: _static/img/gftt_response.png

    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	   torchsqrtabsminr.   r/   )r   r   r   r0   r1   r2   r3   r4   r5   r6   r7   e1e2r8   r   r   r   gftt_response~   s   3
""r@   c                 C   s   t | g d |dur2t|tstdt| t|jdkr*|d| dkr2t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rr||
dd	ddd }|S )
a  Compute the absolute of determinant of the Hessian matrix.

    .. image:: _static/img/hessian_response.png

    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   r0   dxxr5   dyyr8   r   r   r   hessian_response   s   7
"rC   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   r   r   r   dog_response  s   
4rE   r   皙?sigma1sigma2c                 C   sN   t | g d t|}t|}t| ||f||f}t| ||f||f}|| S )aS  Compute the Difference-of-Gaussian response.

    .. image:: _static/img/dog_response_single.png

    Args:
        input: a given the gaussian 4d tensor :math:`(B, C, H, W)`.
        sigma1: lower gaussian sigma
        sigma2: bigger gaussian sigma

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

    r   )r   r   r	   )r   rG   rH   ks1ks2g1g2r   r   r   dog_response_single%  s   rM   c                       sL   e Zd ZdZd fddZdefddZdded	ee defd
dZ	  Z
S )BlobDoGzzModule that calculates Difference-of-Gaussians blobs.

    See
    :func: `~kornia.feature.dog_response` for details.
    r   Nc                    s   t    d S N)super__init__self	__class__r   r   rQ   B     zBlobDoG.__init__c                 C   s   | j jS rO   )rU   __name__rR   r   r   r   __repr__E     zBlobDoG.__repr__r   r   c                 C   s   t |S rO   )rE   rS   r   r   r   r   r   forwardH  rY   zBlobDoG.forward)r   NrO   )rW   
__module____qualname____doc__rQ   strrX   r   r   r[   __classcell__r   r   rT   r   rN   ;  s
    $rN   c                       sZ   e Zd ZdZddededdf fdd	Zdefd
dZddede	e defddZ
  ZS )BlobDoGSinglezModule that calculates Difference-of-Gaussians blobs.

    .. image:: _static/img/dog_response_single.png

    See :func:`~kornia.feature.dog_response_single` for details.
    r   rF   rG   rH   r   Nc                    s   t    || _|| _d S rO   )rP   rQ   rG   rH   )rS   rG   rH   rT   r   r   rQ   T  s   

zBlobDoGSingle.__init__c                 C      | j j d| j d| j dS )Nz	, sigma1=z	, sigma2=))rU   rW   rG   rH   rR   r   r   r   rX   Y     zBlobDoGSingle.__repr__r   r   c                 C   s   t || j| jS rO   )rM   rG   rH   rZ   r   r   r   r[   \  s   zBlobDoGSingle.forwardr   rF   rO   )rW   r\   r]   r^   floatrQ   r_   rX   r   r   r[   r`   r   r   rT   r   ra   L  s
    $ra   c                       sl   e Zd ZU dZeed< ddeeef deddf fddZ	defd	d
Z
ddedee defddZ  ZS )CornerHarriszModule that calculates Harris corners.

    .. image:: _static/img/harris_response.png

    See :func:`~kornia.feature.harris_response` for details.
    r   r   r   r   Nc                    s<   t    t|tr| dt| n| d| || _d S )Nr   )rP   rQ   r'   rf   register_bufferr   r   )rS   r   r   rT   r   r   rQ   j  s
   


zCornerHarris.__init__c                 C   rb   )Nz(k=z, grads_mode=rc   )rU   rW   r   r   rR   r   r   r   rX   r  rd   zCornerHarris.__repr__r   r   c                 C   s   t || j| j|S rO   )r9   r   r   rZ   r   r   r   r[   u  s   zCornerHarris.forwardr   rO   )rW   r\   r]   r^   r   __annotations__r   rf   r_   rQ   rX   r   r[   r`   r   r   rT   r   rg   `  s   
 $$rg   c                       V   e Zd ZdZddeddf fddZdefdd	Zdd
edee defddZ	  Z
S )
CornerGFTTzModule that calculates Shi-Tomasi corners.

    .. image:: _static/img/gftt_response.png

    See :func:`~kornia.feature.gftt_response` for details.
    r   r   r   Nc                       t    || _d S rO   rP   rQ   r   rS   r   rT   r   r   rQ        

zCornerGFTT.__init__c                 C      | j j d| j dS Nz(grads_mode=rc   rU   rW   r   rR   r   r   r   rX        zCornerGFTT.__repr__r   r   c                 C      t || j|S rO   )r@   r   rZ   r   r   r   r[     rV   zCornerGFTT.forwardri   rO   rW   r\   r]   r^   r_   rQ   rX   r   r   r[   r`   r   r   rT   r   rl   y  
    $rl   c                       rk   )BlobHessianzModule that calculates Hessian blobs.

    .. image:: _static/img/hessian_response.png

    See :func:`~kornia.feature.hessian_response` for details.
    r   r   r   Nc                    rm   rO   rn   ro   rT   r   r   rQ     rp   zBlobHessian.__init__c                 C   rq   rr   rs   rR   r   r   r   rX     rt   zBlobHessian.__repr__r   r   c                 C   ru   rO   )rC   r   rZ   r   r   r   r[     rV   zBlobHessian.forwardri   rO   rv   r   r   rT   r   rx     rw   rx   )r   r   N)r   Nre   )typingr   r   r:   kornia.corer   r   r   kornia.core.checkr   kornia.filtersr	   r
   rf   r   r   r_   r9   r@   rC   rE   rM   rN   ra   rg   rl   rx   r   r   r   r   <module>   s6   

 W KM