
    3jS                    X   % S SK Jr  S SKJr  S SKJrJr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  S SKJr  S	S
KJr  \ " S S5      5       rS(S)S jjrS*S+S jjrS,S jrS-S jr      S.S jr " S S\R6                  5      r " S S5      r " S S\R6                  5      r      S/                 S0S jjr " S S\R6                  5      r  " S S\R6                  5      r! " S S\R6                  5      r"SS S S!S".r#S#\$S$'   S%r% " S& S'\R6                  5      r&g)1    )annotations)	dataclass)AnyCallableOptionalTupleN)nn)_pair)grayscale_to_rgb)nms2d   )deform_conv2dc                  V    \ rS rSr% SrS\S'   S\S'   S\S'   \SS j5       rSS jrS	r	g
)ALIKEDFeaturesL   a_  Keypoints, descriptors and scores detected by ALIKED for a single image.

Since ALIKED detects a varying number of keypoints per image,
``ALIKEDFeatures`` is not batched.

Args:
    keypoints: pixel coordinates ``(N, 2)`` as ``[x, y]``.
    descriptors: L2-normalised descriptors ``(N, D)``.
    keypoint_scores: detection confidence scores ``(N,)``.
torch.Tensor	keypointsdescriptorskeypoint_scoresc                4    U R                   R                  S   $ )zNumber of detected keypoints.r   )r   shape)selfs    V/home/wildlama/miniconda3/lib/python3.13/site-packages/kornia/feature/aliked/aliked.pynALIKEDFeatures.n]   s     ~~##A&&    c           	         [        U R                  R                  " U0 UD6U R                  R                  " U0 UD6U R                  R                  " U0 UD65      $ )z)Move all tensors to a new device / dtype.)r   r   tor   r   )r   argskwargss      r   r   ALIKEDFeatures.tob   sX    NNt.v.00  ##T4V4
 	
r    N)returnint)r   r   r    r   r#   r   )
__name__
__module____qualname____firstlineno____doc____annotations__propertyr   r   __static_attributes__r"   r   r   r   r   L   s2    	 !!' '
r   r   c                0    [         R                  " XSUSS9$ )Nr   F)kernel_sizestridebiasr	   Conv2d)	in_planes
out_planesr/   s      r   _conv1x1r5   p   s    99Y&uUUr   c                8    [         R                  " U USUUUSUS9$ )N   F)r.   r/   paddinggroupsr0   dilationr1   )r3   r4   r/   r9   r:   s        r   _conv3x3r;   t   s+    99	 	r   c                   U R                   u  p4nXS-  -
  S-   R                  5       nUSS2S4   R                  SUS-
  U-
  S9USS2S4'   USS2S4   R                  SUS-
  U-
  S9USS2S4'   [        R                  " SU5      n[        R
                  " XwSS9u  p[        R                  " X45      R                  SSS5      R                  S5      n
U
R                  U5      US   -   n
U
R                  S	S5      nU R                  SSS5      [        UR                  5      SSS	2      nUR                  X"S	U5      nUR                  SS
SS5      $ )zFExtract ps x ps patches centred at required_corners from a CHW tensor.   r   Nr   )minmaxijindexing)NNr7   )r   longclamptorcharangemeshgridstackpermute	unsqueezer   reshapetupleT)tensorrequired_cornerspschwcorneroffsetxypatchesptssampleds                r   get_patchesr\      sF   llGA!a'!+113F!Q$<%%!Q%<F1a4L!Q$<%%!Q%<F1a4L\\!R F>>&48DAkk1&!))!Q2<<Q?Gjj 6*#55G
//"a
 CnnQ1%eCEEl4R4&89Goobb!,G??1aA&&r   c                L   U R                   nU R                   [        R                  [        R                  4;   a  U R	                  5       n [        R
                  R                  U 5      u  p#UR                  SS9R                  5       nX4SS2SSS24   -  R                  U5      $ )a  Build a 2x2 affine matrix from a batch of 2x2 covariance matrices.

The affine is ``U @ diag(sqrt(eigenvalues))``, where ``U`` contains the
orthonormal eigenvectors of ``cov`` as *columns*.  This gives an ellipse
whose axes align with the principal directions of the covariance.

Args:
    cov: symmetric positive-semi-definite matrices ``(N, 2, 2)``.

Returns:
    Affine matrices ``(N, 2, 2)``.
g:0yE>)r>   N)
dtyperF   float16bfloat16floatlinalgeighrE   sqrtr   )cov
orig_dtypeeigenvalueseigenvectorsscaless        r   _affine_from_covrj      s      J
yyU]]ENN33iik % 1 1# 6K4(--/F!T1*--11*==r   c                P    U R                  S5      n[        R                  " X/SS9$ )a9  Assemble a ``(N, 2, 3)`` LAF from pixel keypoints and 2x2 affine matrices.

Args:
    keypoints_px: ``(N, 2)`` pixel coordinates ``[x, y]``.
    affine: ``(N, 2, 2)`` affine (rotation+scale) part of the LAF.

Returns:
    LAF tensor ``(N, 2, 3)`` following the kornia convention
    ``[[a, b, cx], [c, d, cy]]``.
rC   dim)rK   rF   cat)keypoints_pxaffinecenterss      r   _laf_from_kpts_and_affinerr      s(     $$R(G99f&B//r   c                  t   ^  \ rS rSrSr    S         SU 4S jjjr   S         S	S jjrSrU =r$ )
DKD   a  Differentiable keypoint detection from a score map.

Args:
    radius: soft detection radius; NMS kernel size is ``2 * radius + 1``.
    top_k: if ``> 0`` return exactly the ``top_k`` highest-scoring
        keypoints; otherwise threshold mode is used.
    scores_th: score threshold when ``top_k <= 0``.
        If ``> 0`` keep keypoints with ``score > scores_th``;
        otherwise keep keypoints above the per-image mean score.
    n_limit: maximum number of keypoints returned in threshold mode.
c                  > [         TU ]  5         Xl        X l        X0l        X@l        SU R                  -  S-   U l        SU l        [        R                  " U R                  U R                  S9U l
        [        R                  " U R                  * U R                  U R                  5      n[        R                  " [        R                  " XU/SS95      R                  SS5      R!                  5       S S 2SS/4   nU R#                  S	U5        g )
Nr=   r   g?)r.   r8   r@   rA   rC   r   hw_grid)super__init__radiustop_k	scores_thn_limitr.   temperaturer	   UnfoldunfoldrF   linspacerI   rH   viewtregister_buffer)r   rz   r{   r|   r}   rW   rw   	__class__s          r   ry   DKD.__init__   s     	
"t{{?Q.iiD,<,<dkkRNNDKK<d6F6FG++ennaVdCDII!RPRRTUVYZ\]X^U^_Y0r   c           
     Z   UR                   u  pVpxUR                  5       n	[        XR                  U R                  45      n
SU
SS2SS2SU R                  2SS24'   SU
SS2SS2SS2SU R                  24'   Uby  [        U5       Hi  nX;   R                  5       u  pSXSS2UR                  5       U R                  -
  S2SS24'   SXSS2SS2UR                  5       U R                  -
  S24'   Mk     O8SU
SS2SS2U R                  * S2SS24'   SU
SS2SS2SS2U R                  * S24'   U R                  S:  aZ  [        R                  " U
R                  US5      U R                  5      n[        U5       Vs/ s H  oR                  U   PM     nnGOEU R                  S:  aY  XR                  :  nUR                  5       S:X  a6  U	R                  US5      R!                  SS9nU
UR                  USSS5      :  nO6U	R                  US5      R!                  SS9nU
UR                  USSS5      :  nUR                  US5      n/ nU	R                  US5      n[#        UU5       Hp  u  nnUR%                  5       SS2S4   n['        U5      U R(                  :  a)  UU   nUR+                  SS9S   nUUSU R(                      nUR-                  U5        Mr     [        R.                  " US-
  US-
  /U	R0                  U	R2                  S9n/ n/ n/ n/ nU(       Ga,  U R5                  U5      n[        U5       GH	  nUU   R7                  5       nUU   n UU    n![        R8                  " U U-  [        R:                  " U US	S
9/SS9n"U!R=                  SS9R>                  R                  5       SS2S4   n#U!U#-
  U R@                  -  RC                  5       n$U$R                  SSS9n%U$U RD                  -  U%-  n&[        RF                  " U RD                  SSS2SS24   U&SS2SSS24   -
  U R                  -  SS9S-  n'U$U'-  R                  SS9U$R                  SS9-  n(U"U&-   n)U)U-  S-  S-
  n)[H        RJ                  " UU   RM                  S5      U)R                  SSSS5      SSS9SSSSS24   n*UR-                  U)5        UR-                  U(5        UR-                  U*5        U(       d  GM  U$U%-  n+U RD                  S   U&SS2S4   -
  n,[        RN                  " SU+U,U,5      n-UR-                  [Q        U-5      5        GM     GON[        U5       GH>  nUU   n [        R8                  " U U-  [        R:                  " U US	S
9/SS9n"U"U-  S-  S-
  n)[H        RJ                  " UU   RM                  S5      U)R                  SSSS5      SSS9SSSSS24   n*UR-                  U)5        UR-                  [        RR                  " U*5      5        UR-                  U*5        U(       d  M  U)R                   S   n.UR-                  [        RT                  " SUR0                  UR2                  S9RM                  S5      RW                  U.SS5      5        GMA     U(       a  UUUU4$ UUU4$ s  snf )u  Detect keypoints from a score map.

Args:
    scores_map: ``(B, 1, H, W)`` detection score map.
    sub_pixel: whether to apply soft-argmax sub-pixel refinement.
    image_size: optional ``(B, 2)`` tensor of valid image sizes ``(W, H)``
        for border masking.
    return_affine: if ``True``, also return per-keypoint 2x2 local affine
        matrices estimated from the soft-argmax weight covariance.

Returns:
    A 3-tuple ``(keypoints, keypoint_scores, score_dispersities)`` — or a
    4-tuple ``(..., local_affines)`` when ``return_affine=True``.
    Each ``keypoints[i]`` is ``(N_i, 2)`` normalised to ``[-1, 1]``.
    Each ``local_affines[i]`` is ``(N_i, 2, 2)`` (only when ``sub_pixel=True``
    and ``return_affine=True``; otherwise identity matrices are returned).
r   NrC   r   rl   T)
descendingdevicer^   trunc)rounding_mode)rm   keepdimr=   bilinearmodealign_cornerszni,nij,nik->njk),r   detachr   r.   rz   rangerD   itemr{   rF   topkr   indicesr|   sumrL   meanzipnonzerolenr}   sortappendrO   r   r^   r   r   rI   divr?   valuesr~   exprw   normFgrid_samplerK   einsumrj   
zeros_likeeyeexpand)/r   
scores_map	sub_pixel
image_sizereturn_affineb_crS   rT   scores_nograd
nms_scoresiiwihr   indices_keypointsmasksthscores_viewmaskscoresr   kpts_scsort_idxwhr   scoredispersitys	kptscoreslocal_affinesrY   b_idxpatchindices_kptpatch_scoreskeypoints_xy_nmsmax_vx_expx_sumxy_residualhw_grid_dist2scoredispersitykeypoints_xykptscoreWdeltare   N_is/                                                  r   forwardDKD.forward   s   0 !&&q"))+=+;+;T=M=M*NO
 ./
1a4;;)*-.
1aMdkkM)*!1X#++-AB
aT[[!8!:A=>AB
aBGGI$;$==> 
 34Jq!dkk\^Q./23Jq!Q./::>::jooa4djjAD:?( C(Qa( C~~!"^^399;!#&..q"5::q:AB&Aq!Q)??E"**1b16616="RZZ1a%;;MM!R(E "'//26K #E; 7f,,.A.w<$,,.$WoG&||t|<Q?H%h~&>?G!((1 !8 \\1q5!a%.1E1E]M`M`a		,.kk*-Gq((*/6$[1#(;; 1_eiiQg&VW$ 
 %((Q(/66==?4H&.$2B2BBGGI		a	6#dll2U: JJdAqj1K4
4KKt{{Z 	  $)=#8"="=!"="DuyyUVyGW"W/+=+b014q8==u%//2 %%aB2#"&	
 Q1*   . ''8  * = A LL.QW1EEE,,'8!UEJC!(()9#)>?[ "^ q/6#(;; 1_eiiQg&VW$   0"4q81<==u%//2 %%aB2#"&	
 Q1*   . ''(8(8(BC  * =&,,Q/C!((		!J,=,=ZEUEUV``abcjjknprtvw' ". i)9=HH)%555M !Ds   9Z()r.   r}   rz   r|   r~   r{   r   )r=   r   皙? N  )
rz   r$   r{   r$   r|   ra   r}   r$   r#   None)TNF)
r   r   r   boolr   Optional[torch.Tensor]r   r   r#   ztuple[list[torch.Tensor], ...]	r%   r&   r'   r(   r)   ry   r   r,   __classcell__r   s   @r   rt   rt      s    
 11 1 	1
 1 
1 1, -1#P6 P6 P6 +	P6
 P6 
(P6 P6r   rt   c                  :    \ rS rSrSrSS	S jjrS
S jrS
S jrSrg)InputPadderi~  zKPad an image so that both spatial dimensions are divisible by ``divis_by``.c                    Xl         X l        X-  S-   U-  U-
  U-  nX#-  S-   U-  U-
  U-  nUS-  XUS-  -
  US-  XDS-  -
  /U l        g )Nr   r=   )htwd_pad)r   rS   rT   divis_bypad_htpad_wds         r   ry   InputPadder.__init__  si    MQ&(2Q6(BMQ&(2Q6(Bq[&Q;"6!VXYkEYZ	r   c                @    [         R                  " XR                  SS9$ )zPad *x* (BCHW).	replicate)r   )r   padr   r   rW   s     r   r   InputPadder.pad  s    uuQ		44r   c                    UR                   S   UR                   S   p2U R                  S   X R                  S   -
  U R                  S   X0R                  S   -
  /nUSUS   US   2US   US   24   $ )z(Remove the padding added by :meth:`pad`.rC   r=   r7   r   r   .)r   r   )r   rW   r   r   rR   s        r   unpadInputPadder.unpad  sw    aggbkBYYq\2		!,diilB1<MNadQqTk1Q4!A$;.//r   )r   r   r   N)   )rS   r$   rT   r$   r   r$   r#   r   rW   r   r#   r   )	r%   r&   r'   r(   r)   ry   r   r   r,   r"   r   r   r   r   ~  s    U[50r   r   c                  l   ^  \ rS rSrSr      S                 SU 4S jjjrSS jrSrU =r$ )	DeformableConv2di  a  Deformable conv2d (DCNv1 or DCNv2) without torchvision dependency.

Uses the pure-PyTorch :func:`~kornia.feature.aliked.deform_conv2d.deform_conv2d`
implementation that matches ``torchvision.ops.deform_conv2d``.

Args:
    in_channels: number of input channels.
    out_channels: number of output channels.
    kernel_size: spatial kernel size.
    stride: convolution stride.
    padding: zero-padding size.
    bias: whether to add a learnable bias.
    mask: if ``True`` use DCNv2 modulation mask (3 * k*k offsets instead of 2).
c	           
     B  > [         T	U ]  5         X@l        XPl        X`l        Xl        U(       a  SU-  U-  OSU-  U-  U l        [        R                  " UU R                  UUU R                  USS9U l	        [        R                  " UUUUU R                  UUS9U l
        g )Nr7   r=   T)r.   r/   r8   r:   r0   )in_channelsout_channelsr.   r/   r8   r:   r0   )rx   ry   r/   r8   r:   r   channel_numr	   r2   offset_convregular_conv)
r   r   r   r.   r/   r8   r:   r0   r   r   s
            r   ry   DeformableConv2d.__init__  s     	 	<@1{?[8a+oXcFc99#LL
 II#%#LL
r   c                   UR                   SS  u  p#[        X#5      S-  nU R                  U5      nU R                  (       aF  [        R
                  " USSS9u  pgn[        R                  " Xg4SS9n	[        R                  " U5      nOUn	S nU	R                  U* U5      n	[        UU	U R                  R                  U R                  R                  U R                  U R                  U R                  US9$ )Nr=         @r7   r   rl   )inputrV   weightr0   r/   r8   r:   r   )r   r?   r   r   rF   chunkrn   sigmoidrE   r   r   r   r0   r/   r8   r:   )
r   rW   rS   rT   
max_offsetouto1o2mask_wrV   s
             r   r   DeformableConv2d.forward  s    wwqr{Y_
q!99"[[aQ7NBFYYxQ/F]]6*FFFzk:6$$++""'';;LL]]	
 		
r   )r   r:   r   r   r8   r   r/   )r7   r   r   r   FF)r   r$   r   r$   r.   r$   r/   r$   r8   r$   r:   r$   r0   r   r   r   r#   r   r   r   r   s   @r   r   r     s    & "
"
 "
 	"

 "
 "
 "
 "
 "
 
"
 "
H
 
r   r   c           
         US:X  a  [         R                  " XX#XES9$ US:X  a  [        U UUU[        U5      S   UUS9$ [	        SU< S35      e)z-Return a standard or deformable conv2d layer.convr.   r/   r8   r0   dcnr   )r.   r/   r8   r0   r   zUnknown conv_type: z. Expected 'conv' or 'dcn'.)r	   r2   r   r
   	TypeError)inplanesplanesr.   r/   r8   r0   	conv_typer   s           r   get_convr    sk     Fyy{[bnnE#'N1%
 	
 ))6QR
SSr   c                  `   ^  \ rS rSrSr    S             SU 4S jjjrSS jrSrU =r$ )		ConvBlocki  z4Two-layer conv block with BN and an activation gate.c                   > [         TU ]  5         Uc  [        R                  " SS9OUU l        Uc  [        R
                  n[        XSXVS9U l        U" U5      U l        [        X"SXVS9U l	        U" U5      U l
        g )NTinplacer7   r.   r
  r   )rx   ry   r	   ReLUgateBatchNorm2dr  conv1bn1conv2bn2)r   r   r   r  
norm_layerr
  r   r   s          r   ry   ConvBlock.__init__  so     	-1\BGGD)t	JkQR[g
l+laS\h
l+r   c                    U R                  U R                  U R                  U5      5      5      nU R                  U R                  U R	                  U5      5      5      $ N)r  r  r  r  r  r   s     r   r   ConvBlock.forward  sA    IIdhhtzz!}-.yy$**Q-011r   )r  r  r  r  r  )NNr  F)r   r$   r   r$   r  "Optional[Callable[..., nn.Module]]r  r  r
  strr   r   r#   r   r   r   r   s   @r   r  r    sl    > 489=,, , 1	,
 7, , , 
, ,$2 2r   r  c                     ^  \ rS rSr% SrSrS\S'            S	                       S
U 4S jjjrSS jrSr	U =r
$ )ResBlocki  zGResidual block (BasicBlock variant) supporting deformable convolutions.r   r$   	expansionc                j  > [         TU ]  5         Uc  [        R                  " SS9U l        OXl        U	c  [        R
                  n	US:w  d  US:w  a  [        S5      eUS:  a  [        S5      e[        XSXS9U l	        U	" U5      U l
        [        X"SXS9U l        U	" U5      U l        X@l        X0l        g )	NTr  r   @   z1ResBlock only supports groups=1 and base_width=64z&Dilation > 1 not supported in ResBlockr7   r  )rx   ry   r	   r  r  r  
ValueErrorNotImplementedErrorr  r  r  r  r  
downsampler/   )r   r  r	  r/   r'  r9   
base_widthr:   r  r  r
  r   r   s               r   ry   ResBlock.__init__  s     	<-DIIJQ;**PQQa<%&NOOhA^
f%f!y\
f%$r   c                
   UnU R                  U R                  U R                  U5      5      5      nU R                  U R	                  U5      5      nU R
                  b  U R                  U5      nU R                  X2-   5      nU$ r  )r  r  r  r  r  r'  )r   rW   identityr   s       r   r   ResBlock.forward=  si    iiA/0hhtzz#'??&q)Hii'
r   )r  r  r  r  r'  r  r/   )	r   Nr   r$  r   NNr  F)r  r$   r	  r$   r/   r$   r'  Optional[nn.Module]r9   r$   r(  r$   r:   r$   r  r  r  r  r
  r  r   r   r#   r   r   )r%   r&   r'   r(   r)   r"  r*   ry   r   r,   r   r   s   @r   r!  r!    s    QIs *.379=  	
 (    1 7   
 @ r   r!  c                  n   ^  \ rS rSrSr     S             SU 4S jjjr      SS jrSrU =r$ )	SDDHiL  a  Sparse descriptor head using deformable sampling positions.

Args:
    dims: input feature dimension.
    kernel_size: patch size used to estimate sampling offsets.
    n_pos: number of deformable sampling positions per keypoint.
    gate: activation function for the offset network.
    conv2d: if ``True`` use a 1x1 conv to aggregate features; otherwise
        use a learnable weighted sum (``agg_weights``).
    mask: if ``True`` use DCNv2-style attention weighting on samples.
c                  > [         TU ]  5         Uc  [        R                  " 5       nX l        X0l        XPl        X`l        [        U l	        U(       a  SU-  OSU-  U l
        [        R                  " [        R                  " XR                  USSSS9U[        R                  " U R                  U R                  SSSSS95      U l        [        R                  " XSSSSS9U l        U(       d>  [        R                  " [         R"                  " X1U5      5      nU R%                  SU5        g [        R                  " X-  USSSSS9U l        g )	Nr7   r=   r   r   Tr  Fagg_weights)rx   ry   r	   r  r.   n_posconv2dr   r\   get_patches_funcr   
Sequentialr2   r   sf_conv	ParameterrF   randregister_parameterconvM)	r   dimsr.   r2  r  r3  r   r1  r   s	           r   ry   SDDH.__init__Y  s    	<779D&
	 +(,1u9!e)==IId,,+aYZaefIId&&(8(8aPQ[\cgh

 yy1aV[\,,uzz%t'DEK##M;?4<1QXY`efDJr   c                   UR                   u  p4pV[        R                  " US-
  US-
  //UR                  UR                  S9n[        XV5      S-  n/ n	/ n
[        U5       GH  nX   X+   pUS-  S-   U-  n[        U5      nU R                  S:  a+  U R                  XR                  5       U R                  5      nOIUR                  5       nUSS2USS2S4   USS2S4   4   R                  SS5      R                  XSS5      nU R                  U5      R                  U* U5      nU R                  (       ah  USS2SS2SS4   R!                  USU R"                  5      R                  SSS5      n[        R$                  " USS2SS2S	4   5      nUSS2SS2SS	24   nO;USS2SS2SS4   R!                  USU R"                  5      R                  SSS5      nSnU	R'                  U5        UR)                  S5      U-   nS
U-  US   -  S-
  nUR                  SXR"                  -  SS5      n[*        R,                  " UR)                  S5      USSS9nUR                  XOU R"                  S5      R                  SSSS5      nUb  [        R.                  " SUU5      n[        R0                  " U R3                  U5      5      R5                  S	5      nU R6                  (       d#  [        R.                  " SUU R8                  5      nOLUR                  US	5      SS2SS2SS4   nU R;                  U5      R5                  S	5      R5                  S	5      n[*        R<                  " US
SS9nU
R'                  U5        GM     X4$ )a  Compute descriptors at keypoint locations.

Args:
    x: dense feature map ``(B, C, H, W)``.
    keypoints: list of ``(N_i, 2)`` normalised keypoint coordinates ``[-1, 1]``.

Returns:
    A pair ``(descriptors, offsets)`` where each element is a list of length B.
r   r   r   r=   g      ?Nr   r7   rC          @r   Tr   zncpo,np->ncpozncp,pcd->ndprm   )r   rF   rO   r   r^   r?   r   r   r.   r4  rD   rJ   rL   r   rE   r   r   r2  r   r   rK   r   r   r   selu_r6  squeezer3  r1  r:  	normalize)r   rW   r   r   rR   rS   rT   r   r   offsets_listr   ibxikptsikptsi_whN_kptsr   kptsi_wh_longrV   r  posfeaturesdescss                          r   r   SDDH.forwardy  s-    WW
a\\AE1q5>*188177KY_
(By}	C2-HZF!#--b--/4CSCST (1mAqD1=A3FFGOOPQSTU]]^dijlmn%%e,22J;
KFyy1a
+00DJJGOOPQSTVWXvaBh'781crc	*1a
+00DJJGOOPQSTVWX'$$Q'&0C)bh&*C++a**!4a;C}}R\\!_c
Z^_H''4::qAII!QPQSTUH! <<6J{{4<<#9:BB2FH;;]Hd>N>NO#++FB71dD8HI

8,44R8@@DKK!4Eu%S V ((r   )	r   r3  r:  r4  r.   r   r2  r   r6  )r7   r   NFF)r;  r$   r.   r$   r2  r$   r  r-  r3  r   r   r   r#   r   )rW   r   r   zlist[torch.Tensor]r#   z-tuple[list[torch.Tensor], list[torch.Tensor]]r   r   s   @r   r/  r/  L  s    
 $(gg g 	g
 "g g g 
g g@@)@) &@) 
7	@) @)r   r/  )r          r$  r$  r7   rO  )rO  rP  r$     rQ  r7   rO  )rO  rP  r$  rQ  rQ  r7   rP  )z
aliked-t16
aliked-n16zaliked-n16rotz
aliked-n32z3dict[str, tuple[int, int, int, int, int, int, int]]_ALIKED_CFGSz:https://github.com/Shiaoming/ALIKED/raw/main/models/{}.pthc                     ^  \ rS rSr% SrSrS\S'       S         SU 4S jjjrSS jrSS jr	 S     SS	 jjr
  S       SS
 jjr\     S           SS jj5       rSrU =r$ )ALIKEDi  at  ALIKED local feature detector and descriptor.

ALIKED (Adaptive Local Image KEypoint Detection) combines a multi-scale
ResNet backbone with deformable descriptor sampling (SDDH) and a
differentiable keypoint detector (DKD).

See :cite:`zhao2023aliked` for details.

.. image:: _static/img/ALIKED.png

Args:
    model_name: backbone configuration, one of
        ``'aliked-t16'``, ``'aliked-n16'``, ``'aliked-n16rot'``, ``'aliked-n32'``.
    max_num_keypoints: maximum number of keypoints to detect.
        ``-1`` means no limit (threshold-based mode).
    detection_threshold: minimum detection score in threshold mode.
    nms_radius: NMS radius (kernel size ``= 2 * nms_radius + 1``).

Example:
    >>> aliked = ALIKED.from_pretrained('aliked-n16')  # doctest: +SKIP
    >>> images = torch.rand(1, 3, 256, 256)  # doctest: +SKIP
    >>> features = aliked(images)  # doctest: +SKIP
r   r$   n_limit_maxc                P  > [         TU ]  5         U[        ;  a   [        SU< S[	        [        5       S35      eXl        X l        X0l        X@l        [        U   u  pVpxpn/ SQnSnSn[        R                  " SSS9U l        [        R                  " SSS9U l        [        R                  U l        [        R                  " S	S
9U l        [#        SXPR                   U R                  US   S9U l        U R'                  XVUS   U5      U l        U R'                  XgUS   U5      U l        U R'                  XxUS   U5      U l        [/        XYS-  5      U l        [/        XiS-  5      U l        [/        XyS-  5      U l        [/        XS-  5      U l        [        R8                  " SSS	S9U l        [        R8                  " SSS	S9U l        [        R8                  " SSS	S9U l        [        R8                  " SSS	S9U l         [        RB                  " [/        U	S5      U R                   [E        SS5      U R                   [E        SS5      U R                   [E        SS5      5      U l#        [I        XXR                   XS9U l%        [M        UUS:  a  SOUUUS:  a  UOU RN                  S9U l(        g )NzUnknown model_name z. Choose from .)r  r  r  r  Fr=   )r.   r/      Tr  r7   r   )r
  r   r   )scale_factorr   r   r   rP  )r  r3  r   rC   )rz   r{   r|   r}   ))rx   ry   rS  r%  list
model_namemax_num_keypointsdetection_threshold
nms_radiusr	   	AvgPool2dpool2pool4r  r   SELUr  r  block1_make_resblockblock2block3block4r5   r  r  conv3conv4Upsample	upsample2	upsample4	upsample8
upsample32r5  r;   
score_headr/  	desc_headrt   rV  dkd)r   r\  r]  r^  r_  c1c2c3c4rm   KM
conv_typesr3  r   r   s                  r   ry   ALIKED.__init__  sE    	\)2:.tT`OaNbbcdee$!2#6 $$0$<!3
\\a:
\\a:
NN	GGD)	2yy$))zRS}U))"*Q-F))"*Q-F))"*Q-Fb(+
b(+
b(+
c!8,
!*TXY!*TXY!*TXY++2JVZ[--S!IIQNIIQNIIQN
 caiiR+a/"5F)):Q)>%DDTDT	
r   c                t    [        UUS[        R                  " XS5      U R                  U R                  UUS9$ )Nr   )r/   r'  r  r  r
  r   )r!  r	   r2   r  r   )r   c_inc_outr
  r   s        r   re  ALIKED._make_resblock!  s:    yya0yy	
 		
r   c                   Sn[        UR                  S   UR                  S   U5      nUR                  U5      nU R                  U5      nU R	                  U R                  U5      5      nU R                  U R                  U5      5      nU R                  U R                  U5      5      nU R                  U R                  U5      5      nU R                  U R                  U5      5      nU R                  U R                  U5      5      nU R                  U R                  U5      5      nU R                  U5      nU R                  U5      n	U R!                  U5      n
["        R$                  " XHX/SS9n["        R&                  " U R)                  U5      5      n[*        R,                  " USSS9nUR/                  U5      nUR/                  U5      nX4$ )ag  Run the backbone and return ``(feature_map, score_map)``.

Args:
    image: ``(B, 3, H, W)`` float image. Inputs are internally padded to
        a multiple of 32 and the padding is removed before returning.

Returns:
    ``feature_map``: ``(B, dim, H, W)`` L2-normalised dense features.
    ``score_map``: ``(B, 1, H, W)`` detection score map in ``(0, 1)``.
rP  r   rC   r   rl   r=   r?  )r   r   r   rd  rf  ra  rg  rb  rh  r  r  r  ri  rj  rl  rn  ro  rF   rn   r   rp  r   rC  r   )r   imagediv_bypadderx1x2x3x4x2_upx3_upx4_upx1234	score_mapfeature_maps                 r   extract_dense_mapALIKED.extract_dense_map-  sj    U[[_ekk"ovF

5![[[[B([[B([[B(YYtzz"~&YYtzz"~&YYtzz"~&YYtzz"~&r"r"#		2e3;MM$//%"89	kk%1!4ll;/LL+	%%r   c           	        UR                   S   S:X  a  [        U5      nU R                  U5      u  p4U R                  XBS9u  pVnU R	                  X55      u  pUR                   S   n
UR                   u    pn[
        R                  " US-
  US-
  /UR                  UR                  S9n/ n[        U
5       H2  nXU   S-   -  S-  nUR                  [        UUU   UU   5      5        M4     U$ )u  Detect and describe local features in a batch of images.

Args:
    images: ``(B, 3, H, W)`` float images (can be grayscale ``(B, 1, H, W)``
        — will be broadcast to 3 channels automatically).
    image_size: optional ``(B, 2)`` tensor of valid ``(W, H)`` for
        border masking when images are padded to a common size.

Returns:
    A list of :class:`ALIKEDFeatures` of length B, one per image.
    Keypoints are in pixel coordinates ``[x, y]``.
r   )r   r   r   r>  )r   r   r  rr  rq  rF   rO   r   r^   r   r   r   )r   imagesr   r  r  r   r   _scoredispersitysr   _offsetsB_rS   rT   r   resultsr   kps_pxs                     r   r   ALIKED.forwardS  s    " <<?a%f-F!%!7!7!?26((9(2\/	/ ${ FLLO\\
1\\1q5!a%.fllSqAQ<!+,s2FNN>&+a.)A,OP  r   c           	        UR                   S   S:X  a  [        U5      nU R                  U5      u  pEUbA  [        R                  " UR                  UR                  5      UR                   SS SSS9nXV-  nU R                  XSS9nU(       a  Uu  ppOUu  pn
SnU R                  XH5      u  pUR                   u  pnn[        R                  " US-
  US-
  /UR                  UR                  S9n/ n[        U5       H  nUUU   S-   -  S	-  nUb  UU   nOYUR                   S
   n[        R                  " SUR                  UR                  S9R                  S
5      R                  USS5      n[!        UU5      nUR#                  U5        M     U(       a  [%        S U 5       5      OS
nSSS jjn[        R&                  " U Vs/ s H  nU" UU5      PM     sn5      n[        R&                  " U	 Vs/ s H  nU" UU5      R                  S5      PM     sn5      n[        R&                  " U Vs/ s H  nU" UU5      PM     sn5      n UUU 4$ s  snf s  snf s  snf )a  Detect and describe local features, returning results in kornia LAF format.

Local Affine Frames are estimated from the soft-argmax weight covariance
computed inside :class:`DKD`: the 2x2 affine matrix captures the dominant
orientation and scale of each detected keypoint without any additional
network parameters.

All per-image tensors are zero-padded along the keypoint dimension so
that the outputs are proper batched tensors.

Args:
    img: image to extract features with shape :math:`(B,C,H,W)`.
    mask: optional spatial mask ``(B, 1, H, W)`` with values in
        ``[0, 1]``; the score map is multiplied by this mask before
        keypoint detection so that features are suppressed in masked
        regions.
    compute_affine: if ``True`` (default), estimate the 2x2 affine shape
        of each LAF using ``torch.linalg.eigh`` on the soft-argmax
        covariance.  Set to ``False`` to skip the eigendecomposition and
        return identity affines, which is faster and avoids the linalg
        call entirely (useful when only keypoint positions are needed).

Returns:
    - Detected local affine frames with shape :math:`(B,N,2,3)`.
    - Response function values for corresponding LAFs with shape :math:`(B,N,1)`.
    - Local descriptors of shape :math:`(B,N,D)`.

r   Nr   r   T)sizer   r   )r   r   r>  r   r=   rC   c              3  >   #    U  H  oR                   S    v   M     g7f)r   N)r   ).0lafs     r   	<genexpr>%ALIKED.forward_laf.<locals>.<genexpr>  s     6ISIIaLIs   c                    XR                   S   -
  nUS:X  a  U $ U4U R                   SS  -   n[        R                  " X R                  XB5      /SS9$ )Nr   r   rl   )r   rF   rn   new_full)r   r   fillpad_n	pad_shapes        r   r    ALIKED.forward_laf.<locals>._pad  sP    
NEz17712;.I99aI!<=1EEr   )g        )r   r   r   r$   r  ra   r#   r   )r   r   r  r   interpolater   r^   rr  rq  rF   rO   r   r   r   rK   r   rr   r   r?   rI   )!r   imgr   compute_affiner  r  mask_rsdkd_outr   r   r  r   r   r  r  r  Hr   r   	lafs_listr   r  affine_ir   laf_in_maxr   r  lafss	responsesdrM  s!                                    r   forward_lafALIKED.forward_lafv  s1   D 99Q<1"3'C!%!7!7!<mm	(yrs/C*dhG "+I((9(CELBI"3]6=3I"3 M ${ FYY
a\\1q5!a%.399M(*	qA9Q<!+,s2F((+ LLO 99QszzKUUVWX__`acegij-fh?EU#  ;D6I66	F {{	B	De,	BCKKy Qy!a!9!9"!=y QR	[A[T!U^[ABY%%	 C QAs   I3"I0Ic                   Uc  [         R                  " S5      nU " UUUUS9R                  U5      n[        R	                  U5      n[         R
                  R                  XuS9nUR                  USS9  UR                  5         U$ )a  Load a pretrained ALIKED model from the official checkpoint repository.

Args:
    model_name: one of ``'aliked-t16'``, ``'aliked-n16'``,
        ``'aliked-n16rot'``, ``'aliked-n32'``.
    max_num_keypoints: passed to :class:`ALIKED` constructor.
    detection_threshold: passed to :class:`ALIKED` constructor.
    nms_radius: passed to :class:`ALIKED` constructor.
    device: target device; defaults to CPU.

Returns:
    Pretrained :class:`ALIKED` in eval mode.
cpu)r\  r]  r^  r_  )map_locationF)strict)	rF   r   r   _CHECKPOINT_URLformathubload_state_dict_from_urlload_state_dicteval)	clsr\  r]  r^  r_  r   modelurl
state_dicts	            r   from_pretrainedALIKED.from_pretrained  s    , >\\%(F!/ 3!	

 "V* 	 $$Z0YY777Q
j7

r   )rd  rf  rg  rh  r  r  ri  rj  rq  r^  rr  r  r]  r\  r_  r   ra  rb  rp  rl  ro  rm  rn  )rR  rC   r   r=   )
r\  r  r]  r$   r^  ra   r_  r$   r#   r   )
r|  r$   r}  r$   r
  r  r   r   r#   r!  )r  r   r#   z!tuple[torch.Tensor, torch.Tensor]r  )r  r   r   r   r#   zlist[ALIKEDFeatures])NT)r  r   r   r   r  r   r#   z/Tuple[torch.Tensor, torch.Tensor, torch.Tensor])rR  rC   r   r=   N)r\  r  r]  r$   r^  ra   r_  r$   r   zOptional[torch.device]r#   rU  )r%   r&   r'   r(   r)   rV  r*   ry   re  r  r   r  classmethodr  r,   r   r   s   @r   rU  rU    s'   0 K '!#%(9
9
 9
 #	9

 9
 
9
 9
v

$&R .2!! +! 
	!L (,#	S&S& %S& 	S&
 
9S&j  '!#%()-!! ! #	!
 ! '! 
! !r   rU  )r   )r3   r$   r4   r$   r/   r$   r#   	nn.Conv2d)r   r   r   )r3   r$   r4   r$   r/   r$   r9   r$   r:   r$   r#   r  )rO   r   rP   r   rQ   r$   r#   r   )re   r   r#   r   )ro   r   rp   r   r#   r   )r7   r   r   Fr  F)r  r$   r	  r$   r.   r$   r/   r$   r8   r$   r0   r   r
  r  r   r   r#   z	nn.Module)'
__future__r   dataclassesr   typingr   r   r   r   rF   torch.nn.functionalr	   
functionalr   torch.nn.modules.utilsr
   kornia.colorr   kornia.geometry.subpixr   r   r   r5   r;   r\   rj   rr   Modulert   r   r   r  r  r!  r/  rS  r*   r  rU  r"   r   r   <module>r     s  p # ! 1 1     ( ) ( ( 
 
 
FV
'*>2000 0.p6")) p6p0 04I
ryy I
^ TTT T 	T
 T T T T T42		 24,ryy ,hm)299 m)l -/2/EA  ObRYY br   