U
    ­Ê¹j�.  ã                	   @   sŠ  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 )&é    )ÚDictÚListÚOptionalÚTupleÚUnionN)Ú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ÚexpandZscatter)r   r   Zfirst_resultr   r   ÚresÚlevelÚindex© r"   úV/var/www/html/bwave/python/venv/lib/python3.8/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    r0   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 )r/   zöDetermine 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>O   s     z(LevelMapper.__call__.<locals>.<listcomp>©r   )ÚminÚmax)r   ÚsqrtÚcatÚfloorr2   Úlog2r1   Útensorr-   r   Úclampr)   r*   ÚtoZint64)r3   r5   ÚsZtarget_lvlsr"   r"   r#   Ú__call__I   s    .zLevelMapper.__call__N)r%   r&   r'   )
Ú__name__Ú
__module__Ú__qualname__Ú__doc__ÚintÚfloatr4   r   r   rC   r"   r"   r"   r#   r/   /   s      úúr/   )Ú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   Zlayoutr   )r   Z	full_likeZstrided)r6   ÚiÚb©r   r   r"   r#   r7   [   s     z*_convert_to_roi_format.<locals>.<listcomp>r   )r   r<   r   r   Ú	enumerate)rJ   Zconcat_boxesZidsÚroisr"   rN   r#   Ú_convert_to_roi_formatW   s    þrQ   )ÚfeatureÚoriginal_sizer   c                 C   sb   | j dd … }g }t||ƒD ]<\}}t|ƒt|ƒ }dtt |¡ ¡  ¡ ƒ }| |¡ q|d S )Néþÿÿÿr   r   )ÚshapeÚziprI   r   r?   r>   ÚroundÚappend)rR   rS   r   Zpossible_scalesÚs1Ús2Zapprox_scaleÚscaler"   r"   r#   Ú_infer_scaleb   s    r\   )Ú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"   )r\   )r6   Zfeat©Zoriginal_input_shaper"   r#   r7   z   s     z!_setup_scales.<locals>.<listcomp>r8   r   ©r+   r,   )	Ú
ValueErrorr:   r   r>   r?   Zfloat32Úitemr0   rH   )r]   r^   r+   r,   Zmax_xZmax_yrU   ÚscalesZlvl_minZlvl_maxÚ
map_levelsr"   r_   r#   Ú_setup_scalesm   s$      üre   )ÚxÚfeatmap_namesr   c                 C   s,   g }|   ¡ D ]\}}||kr| |¡ q|S r.   )ÚitemsrX   )rf   rg   Ú
x_filteredÚkÚvr"   r"   r#   Ú_filter_input‰   s
    rl   )ri   rJ   Úoutput_sizeÚsampling_ratiorc   Úmapperr   c                 C   s$  |dks|dk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¡||< q¨t ¡ �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)
    Nz$scales and mapper should not be Noner   r   )rm   Zspatial_scalern   r   )ra   r   rQ   r   rU   r   r   r   r   rO   rV   r   ÚtorchvisionZ_is_tracingrX   rA   r$   )ri   rJ   rm   rn   rc   ro   Z
num_levelsrP   r   Znum_roisZnum_channelsr   r   ÚresultZtracing_resultsr    Zper_level_featurer[   Zidx_in_levelZrois_per_levelZresult_idx_in_levelr"   r"   r#   Ú_multiscale_roi_align’   sT    ûþüù
û	

rr   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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])

    )rc   rd   r%   r&   r`   )rg   rm   rn   r+   r,   c                   sV   t ƒ  ¡  t| ƒ t|tƒr$||f}|| _|| _t|ƒ| _d | _	d | _
|| _|| _d S r.   )Úsuperr4   r   Ú
isinstancerH   rg   rn   Útuplerm   rc   rd   r+   r,   )r3   rg   rm   rn   r+   r,   ©Ú	__class__r"   r#   r4     s    	


zMultiScaleRoIAlign.__init__)rf   rJ   r^   r   c                 C   sT   t || jƒ}| jdks | jdk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)
rl   rg   rc   rd   re   r+   r,   rr   rm   rn   )r3   rf   rJ   r^   ri   r"   r"   r#   Úforward!  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=ú))rx   rD   rg   rm   rn   )r3   r"   r"   r#   Ú__repr__C  s    $ÿzMultiScaleRoIAlign.__repr__)rD   rE   rF   rG   r   r   rI   r/   Ú__annotations__Ústrr   rH   r   r4   r   r   ry   r{   Ú__classcell__r"   r"   rw   r#   rs   æ   s"   #ùù
û"rs   )r%   r&   r'   )!Útypingr   r   r   r   r   r   Ztorch.fxrp   r   r   Ztorchvision.ops.boxesr
   Úutilsr   r   ZjitZunusedr$   rH   rI   r0   r/   rQ   r\   ZfxÚwrapre   r}   rl   rr   ÚModulers   r"   r"   r"   r#   Ú<module>   sR      ûû
(   þ$
ùS