
    hzK                        S SK r S SKJr  S SKJr  S SKJr  S SKJrJ	r	J
r
JrJrJr  S SKrS SKr\ " S S5      5       rS rS	\\R&                     4S
 jr " S S5      r SAS\R&                  S\\   S\R&                  S\R&                  S\S\R&                  4S jjr SAS\R&                  S\\   S\\   S\S\R&                  4
S jjrS\R&                  S\R&                  4S jrS\S\
\\   SS4   4S jrS\R&                  S\\	\\4      4S jrS\	\\4   S\R<                  4S jrS\R&                  S\R&                  \R&                  44S jr S\R&                  S\R&                  S \R&                  S\R&                  \R&                  44S! jr!S\R&                  S\4S" jr"S#\4S$ jr#S\R&                  S\\	\\4      4S% jr$S\	\\4   S\4S& jr%S'\R&                  S(\S)\S\R&                  4S* jr&S+\S\R<                  4S, jr'S+\S-\S.\S\\R<                     4S/ jr(S0\\S14   S-\S2\S\\\\      \\   4   4S3 jr)S\R&                  S\\   S\R&                  4S4 jr*S5\R&                  S\\   S\R&                  4S6 jr+S'\R&                  S\\   S7\S8\S\R&                  4
S9 jr,S:\R<                  S;\S<\S\\R<                  \-4   4S= jr.S>\	\\4   S\	\\4   4S? jr/S'\R&                  S\R&                  4S@ jr0g)B    Ndeepcopy)	dataclass)product)AnyDict	Generator	ItemsViewListTuplec                   v    \ rS rSr% \R
                  \S'   \R
                  \S'   \\S'   \\S'   \\S'   S rSr	g	)
RLEData   alt_lens_ntcounts_initbhwc                     U R                   $ N)r   selfs    X/home/james-whalen/.local/lib/python3.13/site-packages/torchao/_models/sam2/utils/amg.py__len__RLEData.__len__   s    vv     N)
__name__
__module____qualname____firstlineno__torchTensor__annotations__intr   __static_attributes__r   r   r   r   r      s*    
F
F
Fr   r   c                     U R                  5       nU R                  5       nUR                  5       nX1   R                  5       nXA   R                  5       n[	        XV5       VVs/ s H  u  pxU[
        R                  " U5      -   PM      n	nn[
        R                  " U	5      R                  UR                  5      n	[
        R                  " USU	5      n
UR                  UR                  5      n[
        R                  R                  XS9$ s  snnf )Nr   lengths)valuesoffsetsdiffcpuzipr"   arangecattodeviceindex_selectnestednested_tensor_from_jagged)ntindexr*   r+   r)   offsets_indexlengths_indexolindicesvalues_indexs              r   nt_index_select_dim_0r>      s    YY[FjjlGllnGN&&(MN&&(M14]1RS1Rvq5<<?"1RGSii ##FMM2G%%fa9L!$$V]]3M<<11,1VV	 Ts   #%D
ntsc                 F   / n/ nU  HO  nUR                  UR                  5       5        UR                  UR                  5       R                  5       5        MQ     [        R
                  " U5      n[        R
                  " U5      n[        R                  R                  XES9$ )Nr(   )appendr*   r+   r,   r"   r0   r4   r5   )r?   
all_valuesall_lengthsr6   
new_valuesnew_lengthss         r   nt_cat_dim_0rF   *   s}    JK"))+&2::<,,./  :&J))K(K<<11*1RRr   c                       \ rS rSrSrSS jrS\S\SS4S jrS\SS4S	 jr	S\S\4S
 jr
S\\\4   4S jrS\R                  SS4S jrSS jrSS jrSrg)MaskData6   zw
A structure for storing masks and their related data in batched format.
Implements basic filtering and concatenation.
returnNc                     UR                  5        HC  n[        U[        [        R                  [
        R                  [        45      (       a  M>   S5       e   [        S0 UD6U l	        g )N=MaskData only supports list, numpy arrays, and torch tensors.r   )
r*   
isinstancelistnpndarrayr"   r#   r   dict_stats)r   kwargsvs      r   __init__MaskData.__init__<   sO    Aa$

ELL'!JKK OK ! nVnr   keyitemc                     [        U[        [        R                  [        R
                  [        45      (       d   S5       eX R                  U'   g )NrL   )rM   rN   rO   rP   r"   r#   r   rR   )r   rW   rX   s      r   __setitem__MaskData.__setitem__C   s>    $rzz5<< IJJ 	
K	
J  Cr   c                     U R                   U	 g r   rR   r   rW   s     r   __delitem__MaskData.__delitem__I   s    KKr   c                      U R                   U   $ r   r]   r^   s     r   __getitem__MaskData.__getitem__L   s    {{3r   c                 6    U R                   R                  5       $ r   )rR   itemsr   s    r   re   MaskData.itemsO   s    {{  ""r   keepc           	         U R                   R                  5        GH  u  p#Uc  S U R                   U'   M  [        U[        R                  5      (       a  X1   U R                   U'   ML  [        U[
        R                  5      (       a=  X1R                  5       R                  5       R                  5          U R                   U'   M  [        U[        5      (       aY  UR                  [        R                  :X  a;  [        U5       VVs/ s H  u  pEX   (       d  M  UPM     snnU R                   U'   GM  [        U[        5      (       a%  U Vs/ s H  oCU   PM	     snU R                   U'   GMP  [        U[        5      (       ac  [        UR                   U5      n[        UUR"                  U   UR%                  S5      UR&                  UR(                  S9U R                   U'   GM  [+        SU S[-        U5       S35      e   g s  snnf s  snf )Nr   r   r   r   r   r   MaskData key  has an unsupported type .)rR   re   rM   r"   r#   rO   rP   detachr-   numpyrN   dtypebool	enumerater   r>   r   r   sizer   r   	TypeErrortype)r   rg   krT   ianew_alt_lens_nts          r   filterMaskData.filterR   sy   KK%%'DAy!%AAu||,,!"AArzz**!";;=#4#4#6#<#<#>!?AAt$$uzz)A09!!H!!HAAt$$04!51A$!5AAw''"7t"L!( / !d 3%**1-cccc"A  -s2KDQRG9TU VWW- ( "I!5s   HH
Hc           	         UR                  5        GH[  u  p#X R                  ;  d  U R                  U   c  [        U5      U R                  U'   M?  [        U[        R
                  5      (       a3  [        R                  " U R                  U   U/SS9U R                  U'   M  [        U[        R                  5      (       a3  [        R                  " U R                  U   U/SS9U R                  U'   M  [        U[        5      (       a+  U R                  U   [        U5      -   U R                  U'   GM#  [        U[        5      (       Ga
  U R                  U   R                  UR                  :X  d   eU R                  U   R                  UR                  :X  d   e[        [        U R                  U   R                  UR                  /5      [        R                  " U R                  U   R                   UR                   /5      U R                  U   R"                  UR"                  -   UR                  UR                  S9U R                  U'   GMC  [%        SU S['        U5       S35      e   g )Nr   dimaxisri   rj   rk   rl   )re   rR   r   rM   r"   r#   r0   rO   rP   concatenaterN   r   r   r   rF   r   r   r   rs   rt   )r   	new_statsru   rT   s       r   r0   MaskData.catk   s   OO%DA#t{{1~'=!)!AAu||,,!&DKKNA+>A!FAArzz**!#Q0C!!LAAt$$!%Q(1+!=AAw''{{1~''133...{{1~''133...!( ,Q33Q]]C! !&		4;;q>+E+Eq}}*U Vkk!n&&,cccc"A  -s2KDQRG9TU VWW- &r   c                    U R                   R                  5        Hm  u  p[        U[        R                  5      (       d  M&  UR                  5       R                  5       R                  5       R                  5       U R                   U'   Mo     g r   )	rR   re   rM   r"   r#   floatrm   r-   rn   )r   ru   rT   s      r   to_numpyMaskData.to_numpy   sZ    KK%%'DA!U\\**!"!1!1!3!7!7!9!?!?!AA (r   r]   )rJ   N)r   rH   rJ   N)r   r   r    r!   __doc__rU   strr   rZ   r_   rb   r
   re   r"   r#   ry   r0   r   r&   r   r   r   rH   rH   6   s    
% s  #  $  s t  s  s  #yc* #X5<< XD X2X2Br   rH   boxescrop_boxcrop_box_torchorig_box_torchatolrJ   c                     [        X5      R                  5       n [        R                  " XSSS24   USS9n[        R                  " XSSS24   USS9n[        R                  " XV) 5      n[        R
                  " USS9$ )zNFilter masks at the edge of a crop, but not at the edge of the original image.Nr   )r   rtol   r|   )uncrop_boxes_xyxyr   r"   iscloselogical_andany)r   r   r   r   r   near_crop_edgenear_image_edges          r   is_box_near_crop_edge_torchr      ss     e.446E]]5q*ASTUNmmE$'+BTUVO&&~7GHN99^++r   orig_boxc                     [         R                  " U[         R                  U R                  S9n[         R                  " U[         R                  U R                  S9n[	        XXEU5      $ )Nro   r2   )r"   	as_tensorr   r2   r   )r   r   r   r   r   r   s         r   is_box_near_crop_edger      sL     __XU[[VN__XU[[VN& r   box_xyxyc                 T    [        U 5      nUS   US   -
  US'   US   US   -
  US'   U$ )N   r      r   r   )r   box_xywhs     r   box_xyxy_to_xywhr      s=    !H1++HQK1++HQKOr   
batch_sizec              '   8  ^#    [        T5      S:  a  [        U4S jT 5       5      (       d   S5       e[        TS   5      U -  [        [        TS   5      U -  S:g  5      -   n[        U5       H"  nT Vs/ s H  oDX0-  US-   U -   PM     snv   M$     g s  snf 7f)Nr   c              3   X   >#    U  H  n[        U5      [        TS    5      :H  v   M!     g7f)r   N)len).0rw   argss     r   	<genexpr>!batch_iterator.<locals>.<genexpr>   s"      FAQ3tAw<!7s   '*z8Batched iteration must have inputs of all the same size.r   )r   allr%   range)r   r   	n_batchesr   args    `   r   batch_iteratorr      s     t9q=S F FFF BF DG
*ST!W
1Ja1O-PPI9EIJTc1>QUj$89TJJ Js   A2B5BBtensorc                    U R                   u  pnU R                  SSS5      R                  S5      n U SS2SS24   U SS2SS24   -  nUR                  5       n/ n[	        U5       H  nXUSS2S4   U:H  S4   n[
        R                  " [
        R                  " S/UR                  UR                  S9US-   [
        R                  " X#-  /UR                  UR                  S9/5      nUSS USS -
  n	XS4   S:X  a  / OS/n
U
R                  U	R                  5       R                  5       R                  5       5        UR                  X#/U
S.5        M     U$ )O
Encodes masks to an uncompressed RLE, in the format expected by
pycoco tools.
r   r   r   Nr   rr   counts)shapepermuteflattennonzeror   r"   r0   r   ro   r2   extendrm   r-   tolistrA   )r   r   r   r   r,   change_indicesoutrv   cur_idxsbtw_idxsr   s              r   mask_to_rle_pytorchr      sH    llGA!^^Aq!$,,Q/F !QR%=6!SbS&>)D\\^N C1X!A"6!";Q">?99aSxO1aeWHNN8??S
 AB<(3B-/d|q(qchoo'++-4467

QFf56  Jr   rlec                     U S   u  p[         R                  " X-  [        S9nSnSnU S    H  nXSXDU-   & XF-  nUS-  nM     UR                  X!5      nUR	                  5       $ )z/Compute a binary mask from an uncompressed RLE.rr   ro   r   Fr   T)rO   emptyrp   reshape	transpose)r   r   r   maskidxparitycounts          r   rle_to_maskr      sp    v;DA88AE&D
CFX"(S;$  <<D>>r   c                 P   U R                   u  pnU R                  SSS5      R                  S5      n U SS2SS24   U SS2SS24   -  n[        R                  " S[
        UR                  S9nUR                  UR                  SSS5      5      n[        R                  " XTU/SS9nU$ )	r   r   r   r   Nr   )r   r   r   r|   )
r   r   r   r"   onesrp   r2   	expand_asnarrowr0   )r   r   r   r   r,   rw   s         r   _mask_to_rle_pytorch_2_0_0r      s     llGA!^^Aq!$,,Q/F !QR%=6!SbS&>)D

6dkk:A 	
DKK1a()A99aq\q)DKr   r,   r   c                    U R                  SSS5      R                  S5      n UR                  SS9nUS S 2S4   nUR                  5       S:X  a  UnUnO8UR	                  SSUR                  S5      S-
  5      nUR	                  SSS5      n[        R                  " XV/5      nXt-
  n[        R                  R                  XsS9nU S S 2S4   S:H  n	X4$ )Nr   r   r   r|   r(   )
r   r   sumnumelr   rr   r"   r0   r4   r5   )
r   r,   r   alt_lensall_cur_idxall_cur_idx_0all_cur_idx_1all_btw_idxr   r   s
             r   _mask_to_rle_pytorch_2_0_1r      s     ^^Aq!$,,Q/FxxAxH A&Ka###**1a1A1A!1Dq1HI#**1a3))]:;K+K,,888WKA,!#K##r   c                    U R                   u  pn[        R                  R                  R	                  S5         [        U 5      nS S S 5        [        R                  R                  R	                  S5         SnUWR                  5       S-   S-  :  d   S5       e[        R                  " UR                  U5       Vs/ s H  ofR                  5       PM     sn5      nS S S 5        [        R                  R                  R	                  S5         [        U WW5      u  pS S S 5        [        WW	XUS9$ ! , (       d  f       N= fs  snf ! , (       d  f       Nq= f! , (       d  f       NA= f)Nz1mask_to_rle_pytorch_2: _mask_to_rle_pytorch_2_0_0zmask_to_rle_pytorch_2: nonzero   iz!Needed more chunks than expected.z1mask_to_rle_pytorch_2: _mask_to_rle_pytorch_2_0_1ri   )r   r"   autogradprofilerrecord_functionr   r   r0   chunkr   r   r   )
r   r   r   r   r,   
num_chunksdr   r   r   s
             r   _mask_to_rle_pytorch_2_0r     s*   llGA!		 	 	0	0;
 *&1
 
	 	 	0	01Q	R 
tzz|j8ZGH 	
/	
H J9O#P9OAIIK9O#PQ 
S 
	 	 	0	0;
 $>D.$
 
 {qQRSS-
 
 $Q 
S	R
 
s6   D26AE=E
EE2
E E
E
E'rle_datac                    [         R                  R                  R                  S5         / nU R                  R                  5       R                  5       nU R                  R                  5       nUR                  5       nUR                  5       nU R                  R                  5       nSn[        [        U R                  5      U5       H_  u  pgX5XRU   -    S S nXRU   -  nU(       a  / OS/n	U	R                  U5        UR                  U R                  U R                   /U	S.5        Ma     S S S 5        U$ ! , (       d  f       W$ = f)Nz(mask_to_rle_pytorch_2: Encode run lengthr   r   r   )r"   r   r   r   r   r+   r,   r*   r   r   r.   r   r   r   rA   r   r   )
r   r   r   r   r   offsetrv   cir   r   s
             r   _mask_to_rle_pytorch_2_1r   )  s   		 	 	0	02
 ''//1668**113??$!((***113xzz*K8EA"Fa[,@A#2FHqk!FRA3FMM(#JJXZZ 8FKL 9
" J#
 
" Js   DD77
Ec                     [         R                  R                  R                  S5         [	        [        U 5      5      sS S S 5        $ ! , (       d  f       g = f)Nmask_to_rle_pytorch_2)r"   r   r   r   r   r   )r   s    r   r   r   >  s6    		 	 	0	01H	I'(@(HI 
J	I	Is   A
Ac                 *    [        U S   SS S2   5      $ )Nr   r   r   )r   )r   s    r   area_from_rler   C  s    s8}QTT"##r   masksmask_thresholdthreshold_offsetc                    XU-   :  R                  S[        R                  S9R                  S[        R                  S9nXU-
  :  R                  S[        R                  S9R                  S[        R                  S9nX4-  $ )z
Computes the stability score for a batch of masks. The stability
score is the IoU between the binary masks obtained by thresholding
the predicted mask logits at high and low values.
r   r   )r   r"   int16int32)r   r   r   intersectionsunionss        r   calculate_stability_scorer   I  s{     
#33	4	Ru{{	#	Ru{{	#  
#33	4	Ru{{	#	Ru{{	# 
 !!r   
n_per_sidec                    SSU -  -  n[         R                  " USU-
  U 5      n[         R                  " USSS24   U S45      n[         R                  " USS2S4   SU 45      n[         R                  " X4/SS9R	                  SS5      nU$ )z;Generates a 2D grid of points evenly spaced in [0,1]x[0,1].r   r   Nr   r~   )rO   linspacetilestackr   )r   r   points_one_sidepoints_xpoints_ypointss         r   build_point_gridr   `  s    !j.!Fkk&!f*jAOwwtQw/*aAHwwq$w/!ZAHXXx*4<<RCFMr   n_layersscale_per_layerc                     / n[        US-   5       H-  n[        XU-  -  5      nUR                  [        U5      5        M/     U$ )z*Generates point grids for all crop layers.r   )r   r%   rA   r   )r   r   r   points_by_layerrv   n_pointss         r   build_all_layer_point_gridsr  j  sJ     O8a< za%789/9: ! r   im_size.overlap_ratioc           	      h   / / pCU u  pV[        XV5      nUR                  SSXe/5        UR                  S5        S n[        U5       H  n	SU	S-   -  n
[        X'-  SU
-  -  5      nU" XjU5      nU" XZU5      n[        U
5       Vs/ s H  n[        X-
  U-  5      PM     nn[        U
5       Vs/ s H  n[        X-
  U-  5      PM     nn[	        UU5       HK  u  nnUU[        UU-   U5      [        UU-   U5      /nUR                  U5        UR                  U	S-   5        MM     M     X44$ s  snf s  snf )zf
Generates a list of crop boxes of different sizes. Each layer
has (2**i)**2 boxes for the ith layer.
r   c                 V    [        [        R                  " X!S-
  -  U -   U-  5      5      $ )Nr   )r%   mathceil)orig_lenn_cropsoverlaps      r   crop_len%generate_crop_boxes.<locals>.crop_len  s'    499g15@GKLMMr   r   r   )minrA   r   r%   r   )r  r   r  
crop_boxes
layer_idxsim_him_w
short_sider  i_layern_crops_per_sider  crop_wcrop_hrv   crop_box_x0crop_box_y0x0y0boxs                       r   generate_crop_boxesr  u  sV     
JDTJ q!T()aN ?1-m0A8H4HIJ$':$':<ABR<ST<SqsF,12<ST<ABR<ST<SqsF,12<ST k;7FBr3rF{D13rF{D3IJCc"gk* 8 #  !! UTs   D*,D/c                     Uu  p#  n[         R                  " X#X#//5      R                  5       nUR                  U R                  SS9n[        U R                  5      S:X  a  UR                  S5      nX-   $ NT)r2   non_blockingr   r   r"   r   
pin_memoryr1   r2   r   r   	unsqueeze)r   r   r  r  _r   s         r   r   r     sk    LBAq\\BB+,-88:FYYellY>F
5;;1!!!$>r   r   c                     Uu  p#  n[         R                  " X#//5      R                  5       nUR                  U R                  SS9n[        U R                  5      S:X  a  UR                  S5      nX-   $ r!  r#  )r   r   r  r  r&  r   s         r   uncrop_pointsr(    sg    LBAq\\B8*%002FYYfmm$Y?F
6<<A!!!$?r   orig_horig_wc                     Uu  pEpgUS:X  a  US:X  a  Xc:X  a  Xr:X  a  U $ X6U-
  -
  X'U-
  -
  pXHU-
  XYU-
  4n
[         R                  R                  R                  X
SS9$ )Nr   )value)r"   nn
functionalpad)r   r   r)  r*  r  r  x1y1pad_xpad_yr/  s              r   uncrop_masksr4    sn     NBB	Qw27r|"W%vb'95rz2rz
*C88""5Q"77r   r   area_threshmodec                 ,   SSK nUS;   d   eUS:H  nX@-  R                  [        R                  5      nUR	                  US5      u  pgpUSS2S4   SS n
[        U
5       VVs/ s H  u  pX:  d  M  US-   PM     nnn[        U5      S:X  a  U S4$ S/U-   nU(       dT  [        U5       Vs/ s H  oU;  d  M
  UPM     nn[        U5      S:X  a#  [        [        R                  " U
5      5      S-   /n[        R                  " X~5      n U S	4$ s  snnf s  snf )
z}
Removes small disconnected regions and holes in a mask. Returns the
mask and an indicator of if the mask has been modified.
r   N)holesislandsr8  r   r   r   FT)cv2astyperO   uint8connectedComponentsWithStatsrq   r   r   r%   argmaxisin)r   r5  r6  r:  correct_holesworking_maskn_labelsregionsstatsr&  sizesrv   ssmall_regionsfill_labelss                  r   remove_small_regionsrI    s    ''''GOM!(00:L"%"B"B<QR"SHu!R%LE'0'7K'7tq1?UQU'7MK
=QU{#%K"'/J/Qk5Iq/J{q ryy/0145K777(D: L
 Ks   "D1	D*	D7Duncompressed_rlec                 r    SSK Jn  U S   u  p#UR                  XU5      nUS   R                  S5      US'   U$ )Nr   )r   rr   r   zutf-8)pycocotoolsr   frPyObjectsdecode)rJ  
mask_utilsr   r   r   s        r   coco_encode_rlerP    sA    .F#DA

 
 !1a
8CM((1CMJr   c                 (   U R                   nUSS u  p#[        U5      S:  a  U R                  SS5      n OU R                  S5      n [        R
                  " U SS9u  pEU[        R                  " X$R                  S9SSS24   -  n[        R
                  " USS9u  puXbU) -  -   n[        R                  " USS9u  p[        R
                  " U SS9u  pU	[        R                  " X9R                  S9SSS24   -  n
[        R
                  " U
SS9u  pXU	) -  -   n
[        R                  " U
SS9u  pX:  Xx:  -  n[        R                  " XX/SS9nX) R                  S5      -  n[        U5      S:  a  UR                  " / USS QS	P76 nU$ US   nU$ )
z
Calculates boxes in XYXY format around masks. Return [0,0,0,0] for
an empty mask. For input shape C1xC2x...xHxW, the output shape is C1xC2x...x4.
Nr   r   r   r|   )r2      )r   r   r   r%  r"   maxr/   r2   r  r   r   )r   r   r   r   	in_heightr&  in_height_coordsbottom_edges	top_edgesin_widthin_width_coordsright_edges
left_edgesempty_filterr   s                  r   batched_mask_to_boxr_    s    KKE:DA
5zA~a$" 99U+LI 5<<:J:J#KDRSG#TTii 0b9OL'	z*::99-26LI ))Er*KHa!Hq!QQOYYB7NK%hY7OIIo26MJ  ,1IJL
++zkHb
QC
))"-
-C 5zA~kk)5":)q) J !fJr   )g      4@)1r	  copyr   dataclassesr   	itertoolsr   typingr   r   r	   r
   r   r   rn   rO   r"   r   r>   r#   rF   rH   r%   r   r   r   r   r   r   r   rP   r   r   r   r   r   r   r   r   r   r  r  r   r(  r4  rp   rI  rP  r_  r   r   r   <module>rd     s     !  ? ?     
WSd5<<( SQB QBr ,<<,3i, LL, LL	,
 , \\,  RV<<#'98<S	IN
\\u||  Ks KiS	48M.N K d38n1E >T#s(^ 

 u|| u||8T ,$LL$ %$>Cll$llELL!$.TU\\ Tg T6w *J%,, J4S#X3G J
$tCH~ $# $"<<")."BG"
\\".  "58	"**""38_""(+""<A""
4S	?DI%&""JU\\ T#Y 5<< %,, $s)  	8<<	8#'9	869	8CF	8
\\	8
**#(03
2::t6d38n c3h +u|| + +r   