a
    PSic1                  	   @   s  d dl Z 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eee ed	d
dZd%eeeeedddZG dd dZee edddZeee edddZejjee eeeef  eeeee ef dddZejjeeef ee ee dddZejjee ee ee eeee  ee ed d!d"ZG d#d$ d$e
j Z!dS )&    N)OptionalListDictTupleUnion)nnTensorbox_area   )_log_api_usage_once   )	roi_align)levelsunmerged_resultsreturnc              	   C   s   |d }|j |j }}tj| d|d|d|df||d}tt|D ]h}t| |kd dddd}|	|d|| d|| d|| d}|
d||| }qR|S )Nr   r   r      dtypedevice)r   r   torchzerossizerangelenwhereviewexpandscatter)r   r   Zfirst_resultr   r   reslevelindex r#   S/var/www/html/django/DPS/env/lib/python3.9/site-packages/torchvision/ops/poolers.py_onnx_merge_levels   s    &r%         ư>k_mink_maxcanonical_scalecanonical_levelepsc                 C   s   t | ||||S N)LevelMapperr)   r#   r#   r$   initLevelMapper&   s    r1   c                   @   s<   e Zd ZdZdeeeeedddZee edd	d
Z	dS )r0   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)   c                 C   s"   || _ || _|| _|| _|| _d S r/   )r*   r+   s0lvl0r.   )selfr*   r+   r,   r-   r.   r#   r#   r$   __init__<   s
    zLevelMapper.__init__)boxlistsr   c                 C   sv   t t dd |D }t | jt || j  t j| j|j	d }t j
|| j| jd}|t j| j t jS )z<
        Args:
            boxlists (list[BoxList])
        c                 S   s   g | ]}t |qS r#   r	   ).0Zboxlistr#   r#   r$   
<listcomp>P       z(LevelMapper.__call__.<locals>.<listcomp>r   )minmax)r   sqrtcatfloorr3   log2r2   tensorr.   r   clampr*   r+   toint64)r4   r6   sZtarget_lvlsr#   r#   r$   __call__J   s    .zLevelMapper.__call__N)r&   r'   r(   )
__name__
__module____qualname____doc__intfloatr5   r   r   rF   r#   r#   r#   r$   r0   0   s      r0   boxesr   c                    sT   t j| dd}|j|j  t j fddt| D dd}t j||gdd}|S )Nr   )dimc              	      s6   g | ].\}}t j|d d d df |t j dqS )Nr   )r   layoutr   )r   	full_likestrided)r7   ibr   r   r#   r$   r8   \   r9   z*_convert_to_roi_format.<locals>.<listcomp>r   )r   r>   r   r   	enumerate)rN   concat_boxesidsroisr#   rU   r$   _convert_to_roi_formatX   s    rZ   featureoriginal_sizer   c                 C   sb   | j dd  }g }t||D ]<\}}t|t| }dtt|   }|| q|d S )Nr   r   )shapeziprL   r   rA   r@   roundappend)r\   r]   r   Zpossible_scaless1s2Zapprox_scalescaler#   r#   r$   _infer_scalec   s    rf   )featuresimage_shapesr,   r-   r   c                    s   |st dd}d}|D ] }t|d |}t|d |}q||f  fdd| D }ttj|d tjd  }ttj|d tjd  }	tt|t|	||d}
||
fS )	Nzimages list should not be emptyr   r   c                    s   g | ]}t | qS r#   )rf   )r7   featZoriginal_input_shaper#   r$   r8   {   r9   z!_setup_scales.<locals>.<listcomp>r:   r   r,   r-   )	
ValueErrorr<   r   r@   rA   float32itemr1   rK   )rg   rh   r,   r-   max_xmax_yr_   scalesZlvl_minZlvl_max
map_levelsr#   rj   r$   _setup_scalesn   s$      rs   )xfeatmap_namesr   c                 C   s,   g }|   D ]\}}||v r|| q|S r/   )itemsrb   )rt   ru   
x_filteredkvr#   r#   r$   _filter_input   s
    rz   )rw   rN   output_sizesampling_ratiorq   mapperr   c                 C   s$  |du s|du rt dt| }t|}|dkrJt| d |||d |dS ||}t|}	| d jd }
| d j| d j }}tj|	|
f| ||d}g }t	t
| |D ]b\}\}}t||kd }|| }t|||||d}t r||| q||j||< qt 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 infered. Default value is None.
        mapper (Optional[LevelMapper]): If none, mapper will be automatically infered. Default value is None.
    Returns:
        result (Tensor)
    Nz$scales and mapper should not be Noner   r   )r{   spatial_scaler|   r   )rl   r   rZ   r   r_   r   r   r   r   rV   r`   r   torchvision_is_tracingrb   rC   r%   )rw   rN   r{   r|   rq   r}   
num_levelsrY   r   Znum_roisnum_channelsr   r   resultZtracing_resultsr!   Zper_level_featurere   Zidx_in_levelZrois_per_levelZresult_idx_in_levelr#   r#   r$   _multiscale_roi_align   sT    
	

r   c                       s   e Zd ZdZeee  ee dZdddee	 e
eee ee f eeed fddZee ed	d
dZeee edddZee eeeef  ddddZee	ef ee eeeef  edddZe	dddZ  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])

    )rq   rr   r&   r'   rk   )ru   r{   r|   r,   r-   c                   sV   t    t|  t|tr$||f}|| _|| _t|| _d | _	d | _
|| _|| _d S r/   )superr5   r   
isinstancerK   ru   r|   tupler{   rq   rr   r,   r-   )r4   ru   r{   r|   r,   r-   	__class__r#   r$   r5     s    	


zMultiScaleRoIAlign.__init__rM   c                 C   s   t d t|S )NzXThe 'convert_to_roi_format' method is deprecated since 0.12 and will be removed in 0.14.)warningswarnrZ   )r4   rN   r#   r#   r$   convert_to_roi_format"  s    
z(MultiScaleRoIAlign.convert_to_roi_formatr[   c                 C   s   t d t||S )NzNThe 'infer_scale' method is deprecated since 0.12 and will be removed in 0.14.)r   r   rf   )r4   r\   r]   r#   r#   r$   infer_scale&  s    
zMultiScaleRoIAlign.infer_scaleN)rg   rh   r   c                 C   s(   t d t||| j| j\| _| _d S )NzUThe 'setup_setup_scales' method is deprecated since 0.12 and will be removed in 0.14.)r   r   rs   r,   r-   rq   rr   )r4   rg   rh   r#   r#   r$   setup_setup_scales*  s    
z%MultiScaleRoIAlign.setup_setup_scales)rt   rN   rh   r   c                 C   sT   t || j}| jdu s | jdu r: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)
        N)
rz   ru   rq   rr   rs   r,   r-   r   r{   r|   )r4   rt   rN   rh   rw   r#   r#   r$   forward2  s    zMultiScaleRoIAlign.forward)r   c                 C   s&   | j j d| j d| j d| j dS )Nz(featmap_names=z, output_size=z, sampling_ratio=))r   rG   ru   r{   r|   )r4   r#   r#   r$   __repr__T  s    zMultiScaleRoIAlign.__repr__)rG   rH   rI   rJ   r   r   rL   r0   __annotations__strr   rK   r   r5   r   r   r   r   r   r   r   __classcell__r#   r#   r   r$   r      s.   #

"r   )r&   r'   r(   )"r   typingr   r   r   r   r   r   torch.fxr   r   r   Ztorchvision.ops.boxesr
   utilsr   r   jitunusedr%   rK   rL   r1   r0   rZ   rf   fxwraprs   r   rz   r   Moduler   r#   r#   r#   r$   <module>   sN      
($
S