a
    
dD@                     @   s   d dl Zd dlZd dlZd dlmZ d dlmZ G dd deZ	dd Z
dd	 Zd
d Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zd d! Zd"d# Zd(d&d'ZdS ))    N)product)ceilc                       s&   e Zd Zd fdd	Zdd Z  ZS )PriorBoxNtrainc                    sR   t t   |d  _|d  _|d  _| _ fdd jD  _d _d S )N	min_sizesstepsclipc                    s0   g | ](}t  jd  | t  jd | gqS )r      )r   
image_size).0stepself m/var/www/html/stable-diffusion-webui/repositories/CodeFormer/facelib/detection/retinaface/retinaface_utils.py
<listcomp>       z%PriorBox.__init__.<locals>.<listcomp>s)	superr   __init__r   r   r   r
   feature_mapsname)r   cfgr
   phase	__class__r   r   r   
   s    


zPriorBox.__init__c              	      s   g }t jD ]\ }j  }tt|d t|d D ]\}}|D ]x}|jd  }|jd  } fdd|d fD }	 fdd|d fD }
t|
|	D ]\}}|||||g7 }qqFq:qt|dd}j	r|j
ddd	 |S )
Nr   r	   c                    s$   g | ]}|j    jd   qS )r	   r   r
   )r   xkr   r   r   r      r   z$PriorBox.forward.<locals>.<listcomp>      ?c                    s$   g | ]}|j    jd   qS )r   r   )r   yr   r   r   r      r      )maxmin)	enumerater   r   r   ranger
   torchTensorviewr   clamp_)r   anchorsfr   ijmin_sizes_kxs_kyZdense_cxZdense_cycycxoutputr   r   r   forward   s    
"zPriorBox.forward)Nr   )__name__
__module____qualname__r   r6   __classcell__r   r   r   r   r      s   	r   c                 C   sB   t jjt| ddddf t| dddf |d}t|S )zPure Python NMS baseline.Nr#   )boxesscoresiou_threshold)torchvisionopsnmsr(   r)   list)detsthreshkeepr   r   r   
py_cpu_nms'   s    rE   c                 C   s`   t | ddddf | ddddf d  | ddddf | ddddf d  fdS )a   Convert prior_boxes to (xmin, ymin, xmax, ymax)
    representation for comparison to point form ground truth data.
    Args:
        boxes: (tensor) center-size default boxes from priorbox layers.
    Return:
        boxes: (tensor) Converted xmin, ymin, xmax, ymax form of boxes.
    N   r	   r(   catr;   r   r   r   
point_form2   s    **rJ   c                 C   sZ   t | ddddf | ddddf  d | ddddf | ddddf  dS )z Convert prior_boxes to (cx, cy, w, h)
    representation for comparison to center-size form ground truth data.
    Args:
        boxes: (tensor) point_form boxes
    Return:
        boxes: (tensor) Converted xmin, ymin, xmax, ymax form of boxes.
    NrF   r	   rG   rI   r   r   r   center_sizeA   s
    *&rK   c                 C   s   |  d}| d}t| ddddf d||d|ddddf d||d}t| ddddf d||d|ddddf d||d}tj|| dd}|dddddf |dddddf  S )al   We resize both tensors to [A,B,2] without new malloc:
    [A,2] -> [A,1,2] -> [A,B,2]
    [B,2] -> [1,B,2] -> [A,B,2]
    Then we compute the area of intersect between box_a and box_b.
    Args:
      box_a: (tensor) bounding boxes, Shape: [A,4].
      box_b: (tensor) bounding boxes, Shape: [B,4].
    Return:
      (tensor) intersection area, Shape: [A,B].
    r   NrF   r	   r%   )sizer(   r%   	unsqueezeexpandr$   clamp)box_abox_bABZmax_xyZmin_xyinterr   r   r   	intersectO   s    

LLrV   c                 C   s   t | |}| dddf | dddf  | dddf | dddf   d|}|dddf |dddf  |dddf |dddf   d|}|| | }|| S )u	  Compute the jaccard overlap of two sets of boxes.  The jaccard overlap
    is simply the intersection over union of two boxes.  Here we operate on
    ground truth boxes and default boxes.
    E.g.:
        A ∩ B / A ∪ B = A ∩ B / (area(A) + area(B) - A ∩ B)
    Args:
        box_a: (tensor) Ground truth bounding boxes, Shape: [num_objects,4]
        box_b: (tensor) Prior boxes from priorbox layers, Shape: [num_priors,4]
    Return:
        jaccard overlap: (tensor) Shape: [box_a.size(0), box_b.size(0)]
    NrF   r      r	   )rV   rN   	expand_as)rQ   rR   rU   area_aarea_bunionr   r   r   jaccardb   s
    
LLr\   c                 C   s  t | ddt jddf |ddddf }t | ddt jddf |ddddf }t j|| dd||k jdd }t j| ddddf | ddddf  dd}t j|ddddf |ddddf  dd}||ddt jf | |  S )zF
    return iou of a and b, numpy version for data augenmentation
    NrF   axisr	   npmaximumnewaxisminimumprodall)abltrbarea_irY   rZ   r   r   r   
matrix_iouu   s    00"22rk   c                 C   s   t | ddt jddf |ddddf }t | ddt jddf |ddddf }t j|| dd||k jdd }t j| ddddf | ddddf  dd}|t |ddt jf d S )zF
    return iof of a and b, numpy version for data augenmentation
    NrF   r]   r	   r_   )rf   rg   rh   ri   rj   rY   r   r   r   
matrix_iof   s
    00"2rl   c
                 C   s0  t |t|}
|
jddd\}}|dddf dk}||ddf }|jd dkrfd||	< d||	< dS |
jddd\}}|d |d |d |d |d |d|d t|dD ]}|||| < q|| }|| }d||| k < t|||}|| }t	|||}|||	< |||	< |||	< dS )a!  Match each prior box with the ground truth box of the highest jaccard
    overlap, encode the bounding boxes, then return the matched indices
    corresponding to both confidence and location preds.
    Args:
        threshold: (float) The overlap threshold used when matching boxes.
        truths: (tensor) Ground truth boxes, Shape: [num_obj, 4].
        priors: (tensor) Prior boxes from priorbox layers, Shape: [n_priors,4].
        variances: (tensor) Variances corresponding to each prior coord,
            Shape: [num_priors, 4].
        labels: (tensor) All the class labels for the image, Shape: [num_obj].
        landms: (tensor) Ground truth landms, Shape [num_obj, 10].
        loc_t: (tensor) Tensor to be filled w/ encoded location targets.
        conf_t: (tensor) Tensor to be filled w/ matched indices for conf preds.
        landm_t: (tensor) Tensor to be filled w/ encoded landm targets.
        idx: (int) current batch index
    Return:
        The matched indices corresponding to 1)location 2)confidence
        3)landm preds.
    r	   TkeepdimNr   g?rF   )
r\   rJ   r$   shapesqueeze_index_fill_r'   rM   encodeencode_landm)	thresholdZtruthspriors	varianceslabelslandmsloc_tZconf_tZlandm_tidxoverlapsZbest_prior_overlapZbest_prior_idxZvalid_gt_idxZbest_prior_idx_filterZbest_truth_overlapZbest_truth_idxr/   matchesconflocZmatches_landmlandmr   r   r   match   s4    




r   c                 C   s   | ddddf | ddddf  d |ddddf  }||d |ddddf   }| ddddf | ddddf  |ddddf  }t ||d  }t ||gdS )a  Encode the variances from the priorbox layers into the ground truth boxes
    we have matched (based on jaccard overlap) with the prior boxes.
    Args:
        matched: (tensor) Coords of ground truth for each prior in point-form
            Shape: [num_priors, 4].
        priors: (tensor) Prior boxes in center-offset form
            Shape: [num_priors,4].
        variances: (list[float]) Variances of priorboxes
    Return:
        encoded boxes (tensor), Shape: [num_priors, 4]
    NrF   r   r	   )r(   logrH   )matchedru   rv   g_cxcyZg_whr   r   r   rr      s
    @ <rr   c                 C   sF  t | | dddf} |dddf d| ddd}|dddf d| ddd}|dddf d| ddd}|dddf d| ddd}t j||||gdd}| ddddddf |ddddddf  }||d |ddddddf   }||dd}|S )	a  Encode the variances from the priorbox layers into the ground truth boxes
    we have matched (based on jaccard overlap) with the prior boxes.
    Args:
        matched: (tensor) Coords of ground truth for each prior in point-form
            Shape: [num_priors, 10].
        priors: (tensor) Prior boxes in center-offset form
            Shape: [num_priors,4].
        variances: (list[float]) Variances of priorboxes
    Return:
        encoded landm (tensor), Shape: [num_priors, 10]
    r      rF   Nr	   rW   dimr"   )r(   reshaperM   rN   rO   rH   )r   ru   rv   Z	priors_cxZ	priors_cyZpriors_wZpriors_hr   r   r   r   rs      s    ****4&rs   c              
   C   s   t |ddddf | ddddf |d  |ddddf   |ddddf t | ddddf |d   fd}|ddddf  |ddddf d 8  < |ddddf  |ddddf 7  < |S )a  Decode locations from predictions using priors to undo
    the encoding we did for offset regression at train time.
    Args:
        loc (tensor): location predictions for loc layers,
            Shape: [num_priors,4]
        priors (tensor): Prior boxes in center-offset form.
            Shape: [num_priors,4].
        variances: (list[float]) Variances of priorboxes
    Return:
        decoded bounding box predictions
    NrF   r   r	   )r(   rH   exp)r~   ru   rv   r;   r   r   r   decode   s    F40,r   c              
   C   s`  |ddddf | ddddf |d  |ddddf   |ddddf | ddddf |d  |ddddf   |ddddf | ddddf |d  |ddddf   |ddddf | ddddf |d  |ddddf   |ddddf | ddddf |d  |ddddf   f}t j|dd	}|S )
a  Decode landm from predictions using priors to undo
    the encoding we did for offset regression at train time.
    Args:
        pre (tensor): landm predictions for loc layers,
            Shape: [num_priors,10]
        priors (tensor): Prior boxes in center-offset form.
            Shape: [num_priors,4].
        variances: (list[float]) Variances of priorboxes
    Return:
        decoded landm predictions
    NrF   r   r#         
   r	   r   rG   )preru   rv   tmprx   r   r   r   decode_landm  s    BBBBBr   c              	   C   s  |ddddddf | ddddddf |d  |ddddddf   |ddddddf t | ddddddf |d   f}t j|dd}|ddddddf  |ddddddf d 8  < |ddddddf  |ddddddf 7  < |S )a  Decode locations from predictions using priors to undo
    the encoding we did for offset regression at train time.
    Args:
        b_loc (tensor): location predictions for loc layers,
            Shape: [num_batches,num_priors,4]
        priors (tensor): Prior boxes in center-offset form.
            Shape: [1,num_priors,4].
        variances: (list[float]) Variances of priorboxes
    Return:
        decoded bounding box predictions
    NrF   r   r	   r   )r(   r   rH   )b_locru   rv   r;   r   r   r   batched_decode)  s    T@<8r   c                 C   s  |ddddddf | ddddddf |d  |ddddddf   |ddddddf | ddddddf |d  |ddddddf   |ddddddf | ddddddf |d  |ddddddf   |ddddddf | ddddddf |d  |ddddddf   |ddddddf | ddddddf |d  |ddddddf   f}t j|dd}|S )	a  Decode landm from predictions using priors to undo
    the encoding we did for offset regression at train time.
    Args:
        pre (tensor): landm predictions for loc layers,
            Shape: [num_batches,num_priors,10]
        priors (tensor): Prior boxes in center-offset form.
            Shape: [1,num_priors,4].
        variances: (list[float]) Variances of priorboxes
    Return:
        decoded landm predictions
    NrF   r   r#   r   r   r   r   rG   )r   ru   rv   rx   r   r   r   batched_decode_landm@  s    TTTTTr   c                 C   s.   | j  }ttjt| | ddd| S )zUtility function for computing log_sum_exp while determining
    This will be used to determine unaveraged confidence loss across
    all examples in a batch.
    Args:
        x (Variable(tensor)): conf_preds from conf layers
    r	   Trm   )datar$   r(   r   sumr   )r   x_maxr   r   r   log_sum_expW  s    
r   r       c                 C   s*  t |dd }|  dkr*|S | dddf }| dddf }| dddf }| dddf }t || || }	|d\}
}|| d }|  }|  }|  }|  }|  }|  }d}| dkr"|d }|||< |d7 }|ddkrq"|dd }t j	|d||d t j	|d||d t j	|d||d t j	|d||d t j
||| d}t j
||| d}t j
||| d	}t j
||| d	}|| || || }|| }t j
|d
d}t j
|d
d}|| }t 	|	d|}|| |	|  }|| }||| }q||fS )a  Apply non-maximum suppression at test time to avoid detecting too many
    overlapping bounding boxes for a given object.
    Args:
        boxes: (tensor) The location preds for the img, Shape: [num_priors,4].
        scores: (tensor) The class predscores for the img, Shape:[num_priors].
        overlap: (float) The overlap thresh for suppressing unnecessary boxes.
        top_k: (int) The Maximum number of box preds to consider.
    Return:
        The indices of the kept boxes with respect to num_priors.
    r   Nr	   rF   rW   r"   )outrL   )r$   g        )r(   r)   rM   fill_longnumelmulsortnewindex_selectrP   
resize_as_le)r;   r<   overlaptop_krD   x1y1x2y2areavrz   xx1yy1xx2yy2whcountr.   rU   Z	rem_areasr[   ZIoUr   r   r   r@   e  sX    

r@   )r    r   )numpyr`   r(   r>   	itertoolsr   mathr   objectr   rE   rJ   rK   rV   r\   rk   rl   r   rr   rs   r   r   r   r   r   r@   r   r   r   r   <module>   s*   :