
    3j-(                     V   % S SK JrJr  S SKrS SKJs  Jr  S SKJr  S SKJ	r	  S SK
JrJr  S SKJrJrJr  S SKJr  SS	KJrJrJr  0 r\\\4   \S
'   S\S'    " S S\R4                  5      r " S S\R4                  5      r " S S\R4                  5      r " S S\R4                  5      rg)    )DictOptionalN)nn)pi)KORNIA_CHECK_LAFKORNIA_CHECK_SHAPE)SpatialGradientget_gaussian_discrete_kernel1dget_gaussian_kernel2d)rad2deg   )extract_patches_from_pyramidget_laf_orientationset_laf_orientationurlszEhttps://github.com/ducha-aiki/affnet/raw/master/pretrained/OriNet.pthorinetc                   j    \ rS rSrSrS\R                  S\R                  S\R                  4S jrSrg)	PassLAF#   zSDummy module to use instead of local feature orientation or affine shape estimator.lafimgreturnc                     U$ )zRun forward.

Args:
    laf: :math:`(B, N, 2, 3)`
    img: :math:`(B, 1, H, W)`

Returns:
    LAF, unchanged :math:`(B, N, 2, 3)`

 )selfr   r   s      T/home/wildlama/miniconda3/lib/python3.13/site-packages/kornia/feature/orientation.pyforwardPassLAF.forward&   s	     
    r   N)	__name__
__module____qualname____firstlineno____doc__torchTensorr   __static_attributes__r   r   r   r   r   #   s+    ]5<< ell u|| r   r   c            	          ^  \ rS rSrSrSS\S\S\SS4U 4S jjjrS\4S	 jr	S
\
R                  S\
R                  4S jrSrU =r$ ) PatchDominantGradientOrientation4   a  Module, which estimates the dominant gradient orientation of the given patches, in radians.

Zero angle points towards right.

Args:
    patch_size: size of the (square) input patch.
    num_angular_bins: number of histogram bins.
    eps: for safe division, and arctan.


patch_sizenum_angular_binsepsr   Nc           	        > [         TU ]  5         Xl        X l        [	        SS5      U l        X0l        [        R                  " SSSSSSS9U l	        [        R                  " 5          [        SS5      U R                  R                  S S & S S S 5        [        U R                  5      S	-  n[        U R                  U R                  4XD4S
5      U l        g ! , (       d  f       NP= f)Nsobelr         Fcircular)kernel_sizepaddingbiaspadding_modeg?g      @T)super__init__r+   num_ang_binsr	   gradientr-   r   Conv1dangular_smoothr%   no_gradr
   weightfloatr   	weighting)r   r+   r,   r-   sigma	__class__s        r   r8   )PatchDominantGradientOrientation.__init__@   s    $,'3 ii1!QUakl]]_,J1c,RD&&q) T__-3./QTYSacgh _s   &$C
C"c                     U R                   R                   SU R                   SU R                   SU R                   S3$ )N(patch_size=z, num_ang_bins=z, eps=))rB   r    r+   r9   r-   r   s    r   __repr__)PatchDominantGradientOrientation.__repr__L   sE    ~~&&'|DOO3DOTXTeTeSfflmqmumulvvwx	
r   patchc           	         [        U/ SQ5        UR                  5       u  p#pEX@R                  :w  d  XPR                  :w  d  US:w  a6  [        SU R                   SU R                   SUR                  5        35      eU R                  R                  UR                  5      R                  UR                  5      U l        U R                  R                  UR                  5      R                  UR                  5      U l        U R                  U5      nUSS2SS2S4   nUSS2SS2S4   n[        R                  " Xw-  X-  -   U R                  -   5      U R                  -  n	[        R                  " XU R                  -   5      S[        -  -   n
[        U R                   5      U
S	[        -  -   -  S[        -  -  n[        R"                  " U5      nX-
  nXR                   -  nUS-   U R                   -  nS	U-
  U	-  nX-  n/ n[%        SU R                   5       Hl  n[&        R(                  " UU:H  R                  UR                  5      U-  UU:H  R                  UR                  5      U-  -   S
5      nUR+                  U5        Mn     [        R,                  " US5      R/                  SSU R                   5      nU R                  U5      R/                  SU R                   5      nUR1                  S5      u  nnU R                   U-   S-
  U R                   -  nUS-   U R                   -  n[        R2                  " USUR5                  SS5      5      R5                  S5      nUn[        R2                  " USUR5                  SS5      5      R5                  S5      nSUU-
  -  UU-   SU-  -
  -  nS[        -  UR                  UR                  5      U-   -  [        U R                   5      -  [        -
  * nU$ )aRun forward.

Args:
    patch: :math:`(B, 1, H, W)`

Returns:
    angle in radians: :math:`(B)`

)B1HWr   z#input shape should be must be [Bx1xxz]. Got Nr   g       @g      ?)r   r   g      ?)r   sizer+   	TypeErrorr@   todtypedevicer<   r:   r%   sqrtr-   atan2r   r?   r9   floorrangeFadaptive_avg_pool2dappendcatviewmaxgatherreshape)r   rJ   _CHrP   rO   gradsgxgymagorio_bigbo0_bigwo1_bigbo1_bigwo0_bigang_bins_listi
ang_bins_iang_binsvaluesindicesindices_leftindices_rightleftcenterrightc_subpixangles                                r   r   (PatchDominantGradientOrientation.forwardQ   sl    	5"67jjlq a??&:a5doo5FaGXX_`e`j`j`l_mn  **5;;7::5<<H"1144U[[ADDU\\R"mmE2 Aq> Aq>!JJrw'8488'CDt~~U!KKM:S2XEd''(C#(N;sRxH++e$/---Q;$"3"33=C'-q$++,A..A!!%++.8GqL;L;LU[[;Y\c;ccekJ   ,	 -
 99]A.33B4;L;LM&&x055b$:K:KL",,q/))G3a74;L;LL 1(9(99||Ha)=)=b!)DEMMbQXq-*?*?A*FGOOPRS$,'4%<#,+FG8wzz%++6ABU4K\K\E]]accdr   )r<   r-   r:   r9   r+   r@   )    $   :0yE>)r    r!   r"   r#   r$   intr?   r8   strrH   r%   r&   r   r'   __classcell__rB   s   @r   r)   r)   4   sa    	
i3 
is 
ie 
i_c 
i 
i
# 

1U\\ 1ell 1 1r   r)   c                      ^  \ rS rSrSrSS\S\SS4U 4S jjjr\SS\	R                  S\S\	R                  4S	 jj5       rS
\	R                  S\	R                  4S jrSrU =r$ )OriNet   ap  Network, which estimates the canonical orientation of the given 32x32 patches, in radians.

Zero angle points towards right. This is based on the original code from paper
"Repeatability Is Not Enough: Learning Discriminative Affine Regions via Discriminability"".
See :cite:`AffNet2018` for more details.

Args:
    pretrained: Download and set pretrained weights to the model.
    eps: to avoid division by zero in atan2.

Returns:
    Angle in radians.

Shape:
    - Input: (B, 1, 32, 32)
    - Output: (B)

Examples:
    >>> input = torch.rand(16, 1, 32, 32)
    >>> orinet = OriNet()
    >>> angle = orinet(input) # 16


pretrainedr-   r   Nc                   > [         TU ]  5         [        R                  " [        R                  " SSSSSS9[        R
                  " SSS9[        R                  " 5       [        R                  " SSSSSSS9[        R
                  " SSS9[        R                  " 5       [        R                  " SSSS	SSS9[        R
                  " SSS9[        R                  " 5       [        R                  " SSSSSSS9[        R
                  " SSS9[        R                  " 5       [        R                  " SS
SS	SSS9[        R
                  " S
SS9[        R                  " 5       [        R                  " S
S
SSSSS9[        R
                  " S
SS9[        R                  " 5       [        R                  " S5      [        R                  " S
S	SSSSS9[        R                  " 5       [        R                  " S5      5      U l
        X l        U(       aL  [        R                  R                  [        S   [        R                   " S5      S9nU R#                  US   SS9  U R%                  5         g )Nr         F)r3   r4   r5   )affine)r3   strider4   r5   r~   r1   @   g      ?   Tr   cpu)map_location
state_dict)strict)r7   r8   r   
SequentialConv2dBatchNorm2dReLUDropoutTanhAdaptiveAvgPool2dfeaturesr-   r%   hubload_state_dict_from_urlr   rW   load_state_dicteval)r   r   r-   pretrained_dictrB   s       r   r8   OriNet.__init__   s   IIaAEBNN2e,GGIIIb"!AquMNN2e,GGIIIb"!AquMNN2e,GGIIIb"!AquMNN2e,GGIIIb"!AquMNN2e,GGIIIb"!AquMNN2e,GGIJJtIIb!1adKGGI  #-
0 #ii@@h^c^j^jkp^q@rO  !>u M		r   rQ   c                 ~    [         R                  " U SSS9u  p#XR                  5       -
  UR                  5       U-   -  $ )zNormalize the input by batch.)rR   T)dimkeepdim)r%   std_meandetach)rQ   r-   spmps       r   _normalize_inputOriNet._normalize_input   s8     |TB IIKBIIK#$566r   rJ   c                     U R                  U R                  U5      5      R                  SS5      n[        R                  " USS2S4   S-   USS2S4   U R
                  -   5      nU$ )rL   rR   r1   Nr   r   r   )r   r   r`   r%   rY   r-   )r   rJ   xyr|   s       r   r   OriNet.forward   s\     ]]40078==b!DBq!tHtOR1X-@Ar   )r-   r   )Fr   )gư>)r    r!   r"   r#   r$   boolr?   r8   staticmethodr%   r&   r   r   r'   r   r   s   @r   r   r      sy    04 e t  B 7ELL 7u 7 7 7U\\ ell  r   r   c            	          ^  \ rS rSrSr SS\S\S\\R                     SS4U 4S jjjr	S\
4S	 jrS
\R                  S\R                  S\R                  4S jrSrU =r$ )LAFOrienter   a  Module, which extracts patches using input images and local affine frames (LAFs).

Then runs :class:`~kornia.feature.PatchDominantGradientOrientation` or
:class:`~kornia.feature.OriNet` on patches and then rotates the LAFs by the estimated angles

Args:
    patch_size:
    num_angular_bins:
    angle_detector: Patch orientation estimator, e.g. :class:`~kornia.feature.PatchDominantGradientOrientation`
      or OriNet.

Nr+   r,   angle_detectorr   c                    > [         TU ]  5         Xl        X l        U   Uc&  [	        U R                  U R                  5      U l        g X0l        g )N)r7   r8   r+   r9   r)   r   )r   r+   r,   r   rB   s       r   r8   LAFOrienter.__init__   sD     	$,!"B4??TXTeTe"fD"0r   c                 h    U R                   R                   SU R                   SU R                   S3$ )NrE   z, angle_detector=rF   )rB   r    r+   r   rG   s    r   rH   LAFOrienter.__repr__   s5    ..))*,t6GGXY]YlYlXmmnoor   r   r   c                    [        U5        [        U/ SQ5        UR                  S5      UR                  S5      :w  a/  [        SUR                  S5       SUR                  S5       35      eUR                  SS u  p4[        X!U R                  5      R                  SSU R                  U R                  5      nU R                  U5      R                  X45      n[        U5      R                  U5      n[        U[        U5      U-   5      nU$ )	z}Run forward.

Args:
    laf: :math:`(B, N, 2, 3)`
    img: :math:`(B, 1, H, W)`

Returns:
    LAF_out: :math:`(B, N, 2, 3)`

)rM   CrO   rP   r   z2Batch size of laf and img should be the same. Got z, Nr1   rR   r   )r   r   rS   
ValueErrorshaper   r+   r`   r   r   view_asr   r   )	r   r   r   rM   Npatchesangles_radians
prev_anglelaf_outs	            r   r   LAFOrienter.forward   s     	3 4588A;#((1+%QRURZRZ[\R]Q^^`adaiaijkal`mnooyy!} <St W \ \4??DOO!
 (,':':7'C'H'H'N(-55nE
 3C9PS]9] ^r   )r   r9   r+   )r~   r   N)r    r!   r"   r#   r$   r   r   r   Moduler8   r   rH   r%   r&   r   r'   r   r   s   @r   r   r      s~     gk
1
169
1PXY[YbYbPc
1	
1 
1p# p5<< ell u||  r   r   )typingr   r   r%   torch.nn.functionalr   
functionalr\   kornia.constantsr   kornia.core.checkr   r   kornia.filtersr	   r
   r   kornia.geometryr   r   r   r   r   r   r   __annotations__r   r   r)   r   r   r   r   r   <module>r      s   $ " !      B a a # W Wd38n XXbii "Nryy NbORYY Od3")) 3r   