
    kh.                        d dl mZmZmZmZmZ d dlZd dlZd dlZd dlm	Z	m
Z
 d dlmZ ddlmZ ddlmZ ej                   j"                  d	e
d
ee
   de
fd       Z	 	 	 d(dededededef
dZ G d d      Zdee
   de
fdZde
dee   defdZej2                  j4                  dee
   deeeef      dededeee   ef   f
d       Zej2                  j4                  deee
f   dee   dee
   fd       Zej2                  j4                  d ee
   dee
   d!ee   d"ed#eee      d$ee   de
fd%       Z G d& d'e	j>                        Z y))    )DictListOptionalTupleUnionN)nnTensor)box_area   )_log_api_usage_once   )	roi_alignlevelsunmerged_resultsreturnc           	      Z   |d   }|j                   |j                  }}t        j                  | j	                  d      |j	                  d      |j	                  d      |j	                  d      f||      }t        t        |            D ]  }t        j                  | |k(        d   j                  dddd      }|j                  |j	                  d      ||   j	                  d      ||   j	                  d      ||   j	                  d            }|j                  d|||         } |S )Nr   r   r      dtypedevice)r   r   torchzerossizerangelenwhereviewexpandscatter)r   r   first_resultr   r   reslevelindexs           S/var/www/teggl/fontify/venv/lib/python3.12/site-packages/torchvision/ops/poolers.py_onnx_merge_levelsr&      s"   #A&L &&(;(;6E
++	Q**1-|/@/@/C\EVEVWXEYZbgpvC s+,- =FeO,Q/44RAqAJJqMU#((+U#((+U#((+	
 kk!U$4U$;<= J    k_mink_maxcanonical_scalecanonical_levelepsc                      t        | ||||      S N)LevelMapper)r(   r)   r*   r+   r,   s        r%   initLevelMapperr0   %   s     ue_osKKr'   c                   J    e Zd ZdZ	 	 	 ddededededef
dZdee   d	efd
Z	y)r/   zDetermine which FPN level each RoI in a set of RoIs should map to based
    on the heuristic in the FPN paper.

    Args:
        k_min (int)
        k_max (int)
        canonical_scale (int)
        canonical_level (int)
        eps (float)
    r(   r)   r*   r+   r,   c                 J    || _         || _        || _        || _        || _        y r.   )r(   r)   s0lvl0r,   )selfr(   r)   r*   r+   r,   s         r%   __init__zLevelMapper.__init__;   s'     

!#	r'   boxlistsr   c           
      P   t        j                  t        j                  |D cg c]  }t        |       c}            }t        j                  | j
                  t        j                  || j                  z        z   t        j                  | j                  |j                        z         }t        j                  || j                  | j                        }|j                  t         j                        | j                  z
  j                  t         j                        S c c}w )z<
        Args:
            boxlists (list[BoxList])
        r   )minmax)r   sqrtcatr
   floorr4   log2r3   tensorr,   r   clampr(   r)   toint64)r5   r7   boxliststarget_lvlss        r%   __call__zLevelMapper.__call__I   s     JJuyy8!L(7"3!LMN kk$))ejjTWW.E"EUYU]U]efelelHm"mnkk+4::4::Nu{{+djj8<<U[[II "Ms   D#N      gư>)
__name__
__module____qualname____doc__intfloatr6   r   r	   rG    r'   r%   r/   r/   /   sa    	  #   	
  Jf J& Jr'   r/   boxesc                 f   t        j                  | d      }|j                  |j                  }}t        j                  t	        |       D cg c]6  \  }}t        j
                  |d d d df   ||t         j                  |      8 c}}d      }t        j                  ||gd      }|S c c}}w )Nr   )dimr   )r   layoutr   )r   r=   r   r   	enumerate	full_likestrided)rR   concat_boxesr   r   ibidsroiss           r%   _convert_to_roi_formatr^   W   s    99U*L ''););EF
))dmnsdtu\`\]_`1bqb51E%--PV	WuC 99c<(a0DK	 	vs   ;B-
featureoriginal_sizec                     | j                   dd  }g }t        ||      D ]j  \  }}t        |      t        |      z  }dt        t        j                  |      j                         j                               z  }|j                  |       l |d   S )Nr   r   )shapeziprP   r   r@   r?   roundappend)r_   r`   r   possible_scaless1s2approx_scalescales           r%   _infer_scalerl   b   s    ==D#%OdM* &BRy59,U5<<5::<BBDEEu%& 1r'   featuresimage_shapesc                 $   |st        d      d}d}|D ]   }t        |d   |      }t        |d   |      }" ||f}| D cg c]  }t        ||       }	}t        j                  t        j
                  |	d   t        j                              j                          }
t        j                  t        j
                  |	d   t        j                              j                          }t        t        |
      t        |      ||      }|	|fS c c}w )Nzimages list should not be emptyr   r   r9   r   r*   r+   )

ValueErrorr;   rl   r   r?   r@   float32itemr0   rO   )rm   rn   r*   r+   max_xmax_yrc   original_input_shapefeatscaleslvl_minlvl_max
map_levelss                r%   _setup_scalesr|   m   s     :;;EE %E!He$E!He$% "5>CKL4l4!56LFL zz%,,vayFGLLNNGzz%,,vbzGHMMOOG GG''	J : Ms   Dxfeatmap_namesc                 f    g }| j                         D ]  \  }}||v s|j                  |        |S r.   )itemsrf   )r}   r~   
x_filteredkvs        r%   _filter_inputr      s>    J	 !1a ! r'   r   output_sizesampling_ratiorx   mapperc                    ||t        d      t        |       }t        |      }|dk(  rt        | d   |||d   |      S  ||      }t        |      }	| d   j                  d   }
| d   j
                  | d   j                  }}t        j                  |	|
f|z   ||      }g }t        t        | |            D ]  \  }\  }}t        j                  ||k(        d   }||   }t        |||||      }t        j                         r!|j                  |j                  |             n|j                  |j
                        ||<    t        j                         rt!        ||      }|S )a  
    Args:
        x_filtered (List[Tensor]): List of input tensors.
        boxes (List[Tensor[N, 4]]): boxes to be used to perform the pooling operation, in
            (x1, y1, x2, y2) format and in the image reference size, not the feature map
            reference. The coordinate must satisfy ``0 <= x1 < x2`` and ``0 <= y1 < y2``.
        output_size (Union[List[Tuple[int, int]], List[int]]): size of the output
        sampling_ratio (int): sampling ratio for ROIAlign
        scales (Optional[List[float]]): If None, scales will be automatically inferred. Default value is None.
        mapper (Optional[LevelMapper]): If none, mapper will be automatically inferred. Default value is None.
    Returns:
        result (Tensor)
    z$scales and mapper should not be Noner   r   )r   spatial_scaler   r   )rq   r   r^   r   rc   r   r   r   r   rV   rd   r   torchvision_is_tracingrf   rB   r&   )r   rR   r   r   rx   r   
num_levelsr]   r   num_roisnum_channelsr   r   resulttracing_resultsr#   per_level_featurerk   idx_in_levelrois_per_levelresult_idx_in_levels                        r%   _multiscale_roi_alignr      s   , ~?@@ZJ!%(DQqM# ))
 	
 E]F4yHa=&&q)LqM''A)=)=6E[[	
 		
 F O-6s:v7N-O H))!5{{6U?3A6l+'#)
 ""$""#6#9#9%#@A $7#9#9&,,#GF< -H0  #FO<Mr'   c                        e Zd ZdZeee      ee   dZddddee	   de
eee   ee   f   ded	ed
ef
 fdZdee	ef   dee   deeeef      defdZde	fdZ xZS )MultiScaleRoIAligna{  
    Multi-scale RoIAlign pooling, which is useful for detection with or without FPN.

    It infers the scale of the pooling via the heuristics specified in eq. 1
    of the `Feature Pyramid Network paper <https://arxiv.org/abs/1612.03144>`_.
    They keyword-only parameters ``canonical_scale`` and ``canonical_level``
    correspond respectively to ``224`` and ``k0=4`` in eq. 1, and
    have the following meaning: ``canonical_level`` is the target level of the pyramid from
    which to pool a region of interest with ``w x h = canonical_scale x canonical_scale``.

    Args:
        featmap_names (List[str]): the names of the feature maps that will be used
            for the pooling.
        output_size (List[Tuple[int, int]] or List[int]): output size for the pooled region
        sampling_ratio (int): sampling ratio for ROIAlign
        canonical_scale (int, optional): canonical_scale for LevelMapper
        canonical_level (int, optional): canonical_level for LevelMapper

    Examples::

        >>> m = torchvision.ops.MultiScaleRoIAlign(['feat1', 'feat3'], 3, 2)
        >>> i = OrderedDict()
        >>> i['feat1'] = torch.rand(1, 5, 64, 64)
        >>> i['feat2'] = torch.rand(1, 5, 32, 32)  # this feature won't be used in the pooling
        >>> i['feat3'] = torch.rand(1, 5, 16, 16)
        >>> # create some random bounding boxes
        >>> boxes = torch.rand(6, 4) * 256; boxes[:, 2:] += boxes[:, :2]
        >>> # original image size, before computing the feature maps
        >>> image_sizes = [(512, 512)]
        >>> output = m(i, [boxes], image_sizes)
        >>> print(output.shape)
        >>> torch.Size([6, 5, 3, 3])

    )rx   r{   rI   rJ   rp   r~   r   r   r*   r+   c                    t         |           t        |        t        |t              r||f}|| _        || _        t        |      | _        d | _	        d | _
        || _        || _        y r.   )superr6   r   
isinstancerO   r~   r   tupler   rx   r{   r*   r+   )r5   r~   r   r   r*   r+   	__class__s         r%   r6   zMultiScaleRoIAlign.__init__  sg     	D!k3'&4K*, -..r'   r}   rR   rn   r   c                 ,   t        || j                        }| j                  | j                  /t	        ||| j
                  | j                        \  | _        | _        t        ||| j                  | j                  | j                  | j                        S )a  
        Args:
            x (OrderedDict[Tensor]): feature maps for each level. They are assumed to have
                all the same number of channels, but they can have different sizes.
            boxes (List[Tensor[N, 4]]): boxes to be used to perform the pooling operation, in
                (x1, y1, x2, y2) format and in the image reference size, not the feature map
                reference. The coordinate must satisfy ``0 <= x1 < x2`` and ``0 <= y1 < y2``.
            image_shapes (List[Tuple[height, width]]): the sizes of each image before they
                have been fed to a CNN to obtain feature maps. This allows us to infer the
                scale factor for each one of the levels to be pooled.
        Returns:
            result (Tensor)
        )
r   r~   rx   r{   r|   r*   r+   r   r   r   )r5   r}   rR   rn   r   s        r%   forwardzMultiScaleRoIAlign.forward!  s    & #1d&8&89
;;$//"9+8L$*>*>@T@T,(DK %KKOO
 	
r'   c                     | j                   j                   d| j                   d| j                   d| j                   dS )Nz(featmap_names=z, output_size=z, sampling_ratio=))r   rK   r~   r   r   )r5   s    r%   __repr__zMultiScaleRoIAlign.__repr__C  sM    ~~&&'t7I7I6J K++,,=d>Q>Q=RRSU	
r'   )rK   rL   rM   rN   r   r   rP   r/   __annotations__strr   rO   r   r6   r   r	   r   r   __classcell__)r   s   @r%   r   r      s    !F "*$u+!6h{F[\O  # /Cy/ 3c
DI56/ 	/ / /* 
V 
 F| 
 5c?+	 

 
 
D
# 
r'   r   rH   )!typingr   r   r   r   r   r   torch.fxr   r   r	   torchvision.ops.boxesr
   utilsr   r   jitunusedr&   rO   rP   r0   r/   r^   rl   fxwrapr|   r   r   r   Moduler   rQ   r'   r%   <module>r      s   5 5     * '   v f &  , LLL L 	L
 
L%J %JP$v, 6 & c u  6l*.uS#X*?RUhk
4;#$ 6 T#v+& tCy T&\   PVP<P cP 	P
 T%[!P [!P P Pfa
 a
r'   