
    khIl                         d Z ddlZ G d de      Zd Zd Zd Zd Z G d	 d
e      Z	d Z
d Zd Zd ZddZe	j                  fdZddZd Zd ZddZddZd ZddZd Zd Zd Zd Zy) zBounding Box List operations for Numpy BoxLists.

Example box operations that are supported:
  * Areas: compute bounding box areas
  * IOU: pairwise intersection-over-union scores
    Nc                   F    e Zd ZdZd Zd Zd Zd Zd Zd Z	d Z
d	 Zd
 Zy)BoxLista}  Box collection.
    BoxList represents a list of bounding boxes as numpy array, where each
    bounding box is represented as a row of 4 numbers,
    [y_min, x_min, y_max, x_max].  It is assumed that all bounding boxes within a
    given list correspond to a single image.
    Optionally, users can add additional related fields (such as
    objectness/classification scores).
    c                    t        |t        j                        st        d      t	        |j
                        dk7  s|j
                  d   dk7  rt        d      |j                  t        j                  k7  r(|j                  t        j                  k7  rt        d      | j                  |      st        d      d|i| _
        y	)
zConstructs box collection.
        Args:
          data: a numpy array of shape [N, 4] representing box coordinates
        Raises:
          ValueError: if bbox data is not a numpy array
          ValueError: if invalid dimensions for bbox data
        zdata must be a numpy array.         z Invalid dimensions for box data.z2Invalid data type for box data: float is required.zNInvalid box data. data must be a numpy array of N*[y_min, x_min, y_max, x_max]boxesN)
isinstancenpndarray
ValueErrorlenshapedtypefloat32float64_is_valid_boxesdata)selfr   s     Y/var/www/teggl/fontify/venv/lib/python3.12/site-packages/effdet/evaluation/np_box_list.py__init__zBoxList.__init__#   s     $

+:;;tzz?a4::a=A#5?@@::#

bjj(@QRR##D) > ? ?dO	    c                 :    | j                   d   j                  d   S )z+Return number of boxes held in collections.r	   r   )r   r   r   s    r   	num_boxeszBoxList.num_boxes6   s    yy!''**r   c                 h    | j                   j                         D cg c]
  }|dk7  s	| c}S c c}w )zReturn all non-box fields.r	   )r   keys)r   ks     r   get_extra_fieldszBoxList.get_extra_fields:   s'    99>>+<aqG|<<<s   
//c                     || j                   v S N)r   r   fields     r   	has_fieldzBoxList.has_field>   s    		!!r   c                     | j                  |      rt        d|z   dz         t        |j                        dk  s |j                  d   | j	                         k7  rt        d      || j
                  |<   y)a  Add data to a specified field.
        Args:
          field: a string parameter used to speficy a related field to be accessed.
          field_data: a numpy array of [N, ...] representing the data associated
              with the field.
        Raises:
          ValueError: if the field is already exist or the dimension of the field
              data does not matches the number of boxes.
        Field zalready existsr   r   z!Invalid dimensions for field dataN)r$   r   r   r   r   r   )r   r#   
field_datas      r   	add_fieldzBoxList.add_fieldA   sl     >>% X-0@@AAz 1$
(8(8(;t~~?O(O@AA%		%r   c                 $    | j                  d      S )zConvenience function for accesssing box coordinates.
        Returns:
          a numpy array of shape [N, 4] representing box corners
        r	   )	get_fieldr   s    r   getzBoxList.getQ   s    
 ~~g&&r   c                 v    | j                  |      st        dj                  |            | j                  |   S )a@  Accesses data associated with the specified field in the box collection.
        Args:
          field: a string parameter used to speficy a related field to be accessed.
        Returns:
          a numpy 1-d array representing data of an associated field
        Raises:
          ValueError: if invalid field
        zfield {} does not exist)r$   r   formatr   r"   s     r   r*   zBoxList.get_fieldX   s6     ~~e$6==eDEEyyr   c                 v    | j                         }|dddf   }|dddf   }|dddf   }|dddf   }||||gS )z}Get corner coordinates of boxes.
        Returns:
         a list of 4 1-d numpy arrays [y_min, x_min, y_max, x_max]
        Nr   r   r      )r+   )r   box_coordinatesy_minx_miny_maxx_maxs         r   get_coordinateszBoxList.get_coordinatese   sV    
 ((*1%1%1%1%ueU++r   c                     |j                   d   dkD  r=t        |j                   d         D ]"  }||df   ||df   kD  s||df   ||df   kD  s" y y)aV  Check whether data fullfills the format of N*[ymin, xmin, ymax, xmin].
        Args:
          data: a numpy array of shape [N, 4] representing box coordinates
        Returns:
          a boolean indicating whether all ymax of boxes are equal or greater than
              ymin, and all xmax of boxes are equal or greater than xmin.
        r   r   r   r/   FT)r   range)r   r   is      r   r   zBoxList._is_valid_boxesq   sg     ::a=14::a=) !1:QT
*d1a4j41:.E ! r   N)__name__
__module____qualname____doc__r   r   r   r$   r(   r+   r*   r5   r    r   r   r   r      s4    $&+="& ' 
,r   r   c                 P    | dddf   | dddf   z
  | dddf   | dddf   z
  z  S )zComputes area of boxes.

    Args:
      boxes: Numpy array with shape [N, 4] holding N boxes

    Returns:
      a numpy array with shape [N*1] representing box areas
    Nr   r   r/   r   r=   )r	   s    r   arear?      s9     !Q$K%1+%%1+ad*CDDr   c                    t        j                  | dd      \  }}}}t        j                  |dd      \  }}}}	t        j                  |t        j                  |            }
t        j                  |t        j                  |            }t        j                  t        j
                  |j                        |
|z
        }t        j                  |t        j                  |	            }t        j                  |t        j                  |            }t        j                  t        j
                  |j                        ||z
        }||z  S )a  Compute pairwise intersection areas between boxes.

    Args:
      boxes1: a numpy array with shape [N, 4] holding N boxes
      boxes2: a numpy array with shape [M, 4] holding M boxes

    Returns:
      a numpy array with shape [N*M] representing pairwise intersection area
    r   r   axis)r   splitminimum	transposemaximumzerosr   )boxes1boxes2y_min1x_min1y_max1x_max1y_min2x_min2y_max2x_max2all_pairs_min_ymaxall_pairs_max_yminintersect_heightsall_pairs_min_xmaxall_pairs_max_xminintersect_widthss                   r   intersectionrX      s     (*xx'B$VVVV')xx'B$VVVVFBLL,@AFBLL,@A

288,>,D,D#EGY\nGnoFBLL,@AFBLL,@Azz"((+=+C+C"DFX[mFmn///r   c                     t        | |      }t        |       }t        |      }t        j                  |d      t        j                  |d      z   |z
  }||z  S )a&  Computes pairwise intersection-over-union between box collections.

    Args:
      boxes1: a numpy array with shape [N, 4] holding N boxes.
      boxes2: a numpy array with shape [M, 4] holding N boxes.

    Returns:
      a numpy array with shape [N, M] representing pairwise iou scores.
    r   rA   r   )rX   r?   r   expand_dims)rH   rI   	intersectarea1area2unions         r   iour_      sR     VV,ILELENN5q)BNN5q,IIIUEur   c                 d    t        | |      }t        j                  t        |      d      }||z  S )a  Computes pairwise intersection-over-area between box collections.

    Intersection-over-area (ioa) between two boxes box1 and box2 is defined as
    their intersection area over box2's area. Note that ioa is not symmetric,
    that is, IOA(box1, box2) != IOA(box2, box1).

    Args:
      boxes1: a numpy array with shape [N, 4] holding N boxes.
      boxes2: a numpy array with shape [M, 4] holding N boxes.

    Returns:
      a numpy array with shape [N, M] representing pairwise ioa scores.
    r   rA   )rX   r   rZ   r?   )rH   rI   r[   areass       r   ioarb      s/     VV,INN4<a0Eur   c                       e Zd ZdZdZdZy)	SortOrderzjEnum class for sort order.

    Attributes:
      ascend: ascend order.
      descend: descend order.
    r   r   N)r9   r:   r;   r<   ASCENDDESCENDr=   r   r   rd   rd      s     FGr   rd   c                 B    | j                         \  }}}}||z
  ||z
  z  S )zComputes area of boxes.

    Args:
      boxlist: BoxList holding N boxes

    Returns:
      a numpy array with shape [N*1] representing box areas
    )r5   )boxlistr1   r2   r3   r4   s        r   area_boxlistri      s.     ")!8!8!:E5%EMeem,,r   c                 R    t        | j                         |j                               S )zCompute pairwise intersection areas between boxes.

    Args:
      boxlist1: BoxList holding N boxes
      boxlist2: BoxList holding M boxes

    Returns:
      a numpy array with shape [N*M] representing pairwise intersection area
    )rX   r+   boxlist1boxlist2s     r   intersection_boxlistrn      s     77r   c                 R    t        | j                         |j                               S )zComputes pairwise intersection-over-union between box collections.

    Args:
      boxlist1: BoxList holding N boxes
      boxlist2: BoxList holding M boxes

    Returns:
      a numpy array with shape [N, M] representing pairwise iou scores.
    )r_   r+   rk   s     r   iou_boxlistrp      s     x||~x||~..r   c                 R    t        | j                         |j                               S )a  Computes pairwise intersection-over-area between box collections.

    Intersection-over-area (ioa) between two boxes box1 and box2 is defined as
    their intersection area over box2's area. Note that ioa is not symmetric,
    that is, IOA(box1, box2) != IOA(box2, box1).

    Args:
      boxlist1: BoxList holding N boxes
      boxlist2: BoxList holding M boxes

    Returns:
      a numpy array with shape [N, M] representing pairwise ioa scores.
    )rb   r+   rk   s     r   ioa_boxlistrr      s     x||~x||~..r   c                 r   |j                   rIt        j                  |      | j                         k\  st        j                  |      dk  rt        d      t        | j                         |ddf         }|| j                         }|D ]*  }| j                  |      }|j                  |||df          , |S )a>  Gather boxes from BoxList according to indices and return new BoxList.

    By default, gather returns boxes corresponding to the input index list, as
    well as all additional fields stored in the boxlist (indexing into the
    first dimension).  However one can optionally only gather from a
    subset of fields.

    Args:
      boxlist: BoxList holding N boxes
      indices: a 1-d numpy array of type int_
      fields: (optional) list of fields to also gather from.  If None (default),
          all fields are gathered from.  Pass an empty fields list to only gather the box coordinates.

    Returns:
      subboxlist: a BoxList corresponding to the subset of the input BoxList specified by indices

    Raises:
      ValueError: if specified field is not contained in boxlist or if the indices are not of type int_
    r   zindices are out of valid range.N.)sizer   amaxr   aminr   r   r+   r   r*   r(   )rh   indicesfields
subboxlistr#   extra_field_datas         r   gather_boxlistr{   	  s    ( ||777w0022bggg6F6J>??wz23J~))+ D",,U3U$4Wc\$BCD r   c                    | j                  |      st        d|z   dz         t        | j                  |      j                        dk7  rt        d|z   dz         |t
        j                  k7  r|t
        j                  k7  rt        d      | j                  |      }t        j                  |      }|t
        j                  k(  r|ddd   }t        | |      S )aR  Sort boxes and associated fields according to a scalar field.

    A common use case is reordering the boxes according to descending scores.

    Args:
        boxlist: BoxList holding N boxes.
        field: A BoxList field for sorting and reordering the BoxList.
        order: (Optional) 'descend' or 'ascend'. Default is descend.

    Returns:
      sorted_boxlist: A sorted BoxList with the field in the specified order.

    Raises:
        ValueError: if specified field does not exist or is not of single dimension.
        ValueError: if the order is not either descend or ascend.
    r&   z does not existr   zshould be single dimension.zInvalid sort orderN)r$   r   r   r*   r   rd   rf   re   r   argsortr{   )rh   r#   orderfield_to_sortsorted_indicess        r   sort_by_field_boxlistr   )  s    " U#E),==>>
7U#))*a/E),IIJJ	!!!ey/?/?&?-..%%e,MZZ.N	!!!'"-'>22r   c           	         | j                  d      st        d      |dk  s|dkD  rt        d      |dk  rt        d      t        | |      } | j                         dk(  r| S t	        | d      } |dk(  r6| j                         |kD  r!t        j                  |      }t        | |      S | S | j                         }| j                         }t        j                  |dt        	      }g }d}t        |      D ]  }	||k  s	||	   s|dz  }|j                  |	       d
||	<   t        j                  |      d   }
|
j                  dk(  r ngt        t        j                   ||	ddf   d      ||
ddf         }t        j"                  |d      }t        j$                  ||
   ||k        ||
<    t        | t        j&                  |            S )aC  Non maximum suppression.

    This op greedily selects a subset of detection bounding boxes, pruning
    away boxes that have high IOU (intersection over union) overlap (> thresh)
    with already selected boxes. In each iteration, the detected bounding box with
    highest score in the available pool is selected.

    Args:
        boxlist: BoxList holding N boxes.  Must contain a 'scores' field
            representing detection scores. All scores belong to the same class.
        max_output_size: maximum number of retained boxes
        iou_threshold: intersection over union threshold.
        score_threshold: minimum score threshold. Remove the boxes with scores less than
            this value. Default value is set to -10. A very low threshold to pass pretty
            much all the boxes, unless the user sets a different score threshold.

    Returns:
        a BoxList holding M boxes where M <= max_output_size
    Raises:
        ValueError: if 'scores' field does not exist
        ValueError: if threshold is not in [0, 1]
      ValueError: if max_output_size < 0
    scoreszField scores does not exist              ?zIOU threshold must be in [0, 1]r   z&max_output_size must be bigger than 0.r   )r   FNrA   )r$   r   filter_scores_greater_thanr   r   r   aranger{   r+   fullboolr7   appendwherert   r_   rZ   squeezelogical_andarray)rh   max_output_sizeiou_thresholdscore_thresholdselected_indicesr	   r   is_index_valid
num_outputr8   valid_indicesintersect_over_unions               r   non_max_suppressionr   H  s   0 X&677r]S0:;;ABB(/BGa#GX6G 0!yy9!'+;<<NKKME!!#IWWY6NJ9 ;'a a
 ''*$)q! " 8 ; %%*'*2>>%1+A+NPUVcefVfPg'h$')zz2FQ'O$02"=1(M91;}-; '288,<#=>>r   c           	         d|cxk  rdk  st        d       t        d      t        | t              st        d      | j                  d      st        d      | j	                  d      }t        |j                        dk(  rt        j                  |ddg      }n=t        |j                        d	k(  r|j                  d   t        d
      t        d      | j                         }|j                  d   }|j                  d   }||k7  rt        d      g }t        |      D ]  }	t        | j                               }
t        j                  |d||	f   dg      }|
j                  d|       t        |
|      }t        ||||      }|j                  dt        j                  |j	                  d            |	z          |j!                  |        t#        |      }t%        |d      }|S )a|  Multi-class version of non maximum suppression.

    This op greedily selects a subset of detection bounding boxes, pruning
    away boxes that have high IOU (intersection over union) overlap (> thresh)
    with already selected boxes.  It operates independently for each class for
    which scores are provided (via the scores field of the input box_list),
    pruning boxes with score less than a provided threshold prior to
    applying NMS.

    Args:
        boxlist: BoxList holding N boxes.  Must contain a 'scores' field
            representing detection scores.  This scores field is a tensor that can
            be 1 dimensional (in the case of a single class) or 2-dimensional, which
            which case we assume that it takes the shape [num_boxes, num_classes].
            We further assume that this rank is known statically and that
            scores.shape[1] is also known (i.e., the number of classes is fixed
            and known at graph construction time).
        score_thresh: scalar threshold for score (low scoring boxes are removed).
        iou_thresh: scalar threshold for IOU (boxes that that high IOU overlap
            with previously selected boxes are removed).
        max_output_size: maximum number of retained boxes per class.

    Returns:
        a BoxList holding M boxes with a rank-1 scores field representing
            corresponding scores for each box with scores sorted in decreasing order
            and a rank-1 classes field representing a class label for each box.
    Raises:
        ValueError: if iou_thresh is not in [0, 1] or if input boxlist does not have
            a valid scores field.
    r   r   zthresh must be between 0 and 1boxlist must be a BoxListr   &input boxlist must have 'scores' fieldr   r}   r   z:scores field must have statically defined second dimensionz#scores field must be of rank 1 or 2z2Incorrect scores field length: actual vs expected.)r   r   r   classes)r   r
   r   r$   r*   r   r   r   reshaper   r7   r+   r(   r   r   
zeros_liker   concatenate_boxlistr   )rh   score_thresh
iou_threshr   r   r   
num_scoresnum_classesselected_boxes_list	class_idxboxlist_and_class_scoresclass_scoresboxlist_filt
nms_resultselected_boxessorted_boxess                   r   multi_class_non_max_suppressionr     s   > 
!c!9:: "9::gw'455X&CDDx(F
6<<AFRG,	V\\	a	<<?"YZZ>??!!#IaJ,,q/KJMNN;' /	#*7;;=#9 zz&:y)@"AB4H **8\B12JLY(/eqs
Yj6J6J86T(UXa(ab"":./ ))<=N(BLr   c                 <   t        j                  | j                         dd      \  }}}}||z  }||z  }||z  }||z  }t        t        j                  ||||g            }| j                         }|D ]%  }	| j                  |	      }
|j                  |	|
       ' |S )zScale box coordinates in x and y dimensions.

    Args:
        boxlist: BoxList holding N boxes
        y_scale: float
        x_scale: float

    Returns:
        boxlist: BoxList holding N boxes
    r   r   rA   )r   array_splitr+   r   hstackr   r*   r(   )rh   y_scalex_scaler1   r2   r3   r4   scaled_boxlistrx   r#   rz   s              r   scaler     s     "$qq!IE5%eOEeOEeOEeOERYYueU'CDEN%%'F :",,U3  (89: r   c                    t        j                  | j                         dd      \  }}}}|d   }|d   }|d   }	|d   }
t        j                  t        j                  ||	      |      }t        j                  t        j                  ||	      |      }t        j                  t        j                  ||
      |      }t        j                  t        j                  ||
      |      }t        t        j                  ||||g            }t        ||       }|rrt        |      }t        j                  t        j                  t        j                  |d            dg      j                  t         j                        }t        ||      }|S )	aH  Clip bounding boxes to a window.

    This op clips input bounding boxes (represented by bounding box
    corners) to a window, optionally filtering out boxes that do not
    overlap at all with the window.

    Args:
        boxlist: BoxList holding M_in boxes
        window: a numpy array of shape [4] representing the [y_min, x_min, y_max, x_max]
            window to which the op should clip boxes.
        filter_nonoverlapping: whether to filter out boxes that do not overlap at all with the window.

    Returns:
        a BoxList holding M_out boxes where M_out <= M_in
    r   r   rA   r   r   r/   r   r}   )r   r   r+   fmaxfminr   r   _copy_extra_fieldsr?   r   nonzerogreaterastypeint32r{   )rh   windowfilter_nonoverlappingr1   r2   r3   r4   	win_y_min	win_x_min	win_y_max	win_x_maxy_min_clippedy_max_clippedx_min_clippedx_max_clippedclippedra   nonzero_area_indicess                     r   clip_to_windowr     s4     "$qq!IE5%q	Iq	Iq	Iq	IGGBGGE95yAMGGBGGE95yAMGGBGGE95yAMGGBGGE95yAMbii}m \]^G '2GW!zz"**RZZs5K*LrdSZZ[][c[cd *>?Nr   c                     t        ||       }t        j                  |d      }t        j                  |t        j                  |            }t        j
                  |      d   }t        | |      }|S )a  Prunes the boxes in boxlist1 that overlap less than thresh with boxlist2.

    For each box in boxlist1, we want its IOA to be more than minoverlap with
    at least one of the boxes in boxlist2. If it does not, we remove it.

    Args:
        boxlist1: BoxList holding N boxes.
        boxlist2: BoxList holding M boxes.
        minoverlap: Minimum required overlap between boxes, to count them as overlapping.

    Returns:
        A pruned boxlist with size [N', 4].
    r   rA   )rb   r   ru   greater_equalr   r   r{   )rl   rm   
minoverlapintersection_over_area	keep_bool	keep_indsnew_boxlist1s          r   prune_non_overlapping_boxesr     sd     !84WW%;!D  !7*9MNI

9%a(I!(I6Lr   c           
         t        j                  | j                         dd      \  }}}}|d   }|d   }|d   }|d   }	t        j                  t        j                  ||      t        j                  ||      t        j
                  ||      t        j
                  ||	      g      }
t        j                  t        j                  t        j                  t        j                  |
d                  dg      }t        | |      |fS )a  Prunes bounding boxes that fall outside a given window.

    This function prunes bounding boxes that even partially fall outside the given
    window. See also ClipToWindow which only prunes bounding boxes that fall
    completely outside the window, and clips any bounding boxes that partially
    overflow.

    Args:
        boxlist: a BoxList holding M_in boxes.
        window: a numpy array of size 4, representing [ymin, xmin, ymax, xmax] of the window.

    Returns:
        pruned_corners: a tensor with shape [M_out, 4] where M_out <= M_in.
        valid_indices: a tensor with shape [M_out] indexing the valid bounding boxes in the input tensor.
    r   r   rA   r   r   r/   r}   )r   r   r+   r   lessr   r   r   logical_notmaxr{   )rh   r   r1   r2   r3   r4   r   r   r   r   coordinate_violationsr   s               r   prune_outside_windowr   "  s    " "$qq!IE5%q	Iq	Iq	Iq	III
y!2775)#<


5)$bjj	&B'D E JJrxxrvv>SZ[7\(]^ac`deM'=1=@@r   c           	         t        | t              st        d      | st        d      | D ]  }t        |t              rt        d       t        t	        j
                  | D cg c]  }|j                          c}            }|| d   j                         }|D ]  }| d   j                  |      j                  }|dd }| D ]Q  }|j                  |      st        d      |j                  |      j                  }|dd }||k7  sEt        d|z         t	        j                  | D cg c]  }|j                  |       c}d	      }|j                  ||        |S c c}w c c}w )
a  Concatenate list of BoxLists.

    This op concatenates a list of input BoxLists into a larger BoxList.  It also
    handles concatenation of BoxList fields as long as the field tensor shapes
    are equal except for the first dimension.

    Args:
      boxlists: list of BoxList objects
      fields: optional list of fields to also concatenate.  By default, all
        fields from the first BoxList in the list are included in the concatenation.

    Returns:
      a BoxList with number of boxes equal to
        sum([boxlist.num_boxes() for boxlist in BoxList])
    Raises:
      ValueError: if boxlists is invalid (i.e., is not a list, is empty, or
        contains non BoxList objects), or if requested fields are not contained in all boxlists
    zboxlists should be a listz#boxlists should have nonzero lengthz2all elements of boxlists should be BoxList objectsNr   r   z)boxlist must contain all requested fieldszLfield %s must have same shape for all boxlists except for the 0th dimension.rA   )r
   listr   r   r   vstackr+   r   r*   r   r$   concatenater(   )boxlistsrx   rh   concatenatedr#   first_field_shapefield_shapeconcatenated_fields           r   r   r   ?  s   & h%455>?? S'7+QRRS 2998%Lgkkm%LMNL~!--/ :$QK11%8>>-ab1 	JG$$U+ !LMM!++E288K%ab/K//  "ACH"I J J	J  ^^U],^'W->->u-E,^efgu&89: ! &M -_s   #E"+E'
c                    t        | t              st        d      | j                  d      st        d      | j	                  d      }t        |j                        dkD  rt        d      t        |j                        dk(  r|j                  d   dk7  rt        d      t        j                  t        j                  t        j                  ||            dg      j                  t        j                        }t        | |      S )	a  Filter to keep only boxes with score exceeding a given threshold.

    This op keeps the collection of boxes whose corresponding scores are
    greater than the input threshold.

    Args:
      boxlist: BoxList holding N boxes.  Must contain a 'scores' field representing detection scores.
      thresh: scalar threshold

    Returns:
      a BoxList holding M boxes where M <= N

    Raises:
      ValueError: if boxlist not a BoxList object or if it does not have a scores field
    r   r   r   r   zScores should have rank 1 or 2r   zAScores should have rank 1 or have shape consistent with [None, 1]r}   )r
   r   r   r$   r*   r   r   r   r   r   r   r   r   r{   )rh   threshr   high_score_indicess       r   r   r   l  s      gw'455X&CDDx(F
6<<19::
6<<A&,,q/Q"6 5 6 	6BHHRZZ-G$H2$OVVWYW_W_`'#566r   c           
          |d   |d   z
  }|d   |d   z
  }t        t        | j                         |d   |d   |d   |d   gz
        d|z  d|z        }t        ||        |S )a  Change coordinate frame of the boxlist to be relative to window's frame.

    Given a window of the form [ymin, xmin, ymax, xmax],
    changes bounding box coordinates from boxlist to be relative to this window
    (e.g., the min corner maps to (0,0) and the max corner maps to (1,1)).

    An example use case is data augmentation: where we are given groundtruth
    boxes (boxlist) and would like to randomly crop the image to some
    window (window). In this case we need to change the coordinate frame of
    each groundtruth box to be relative to this new window.

    Args:
      boxlist: A BoxList object holding N boxes.
      window: a size 4 1-D numpy array.

    Returns:
      Returns a BoxList object with N boxes.
    r   r   r/   r   r   )r   r   r+   r   )rh   r   
win_height	win_widthboxlist_news        r   change_coordinate_framer     s    & VAY&Jq	F1I%IF1Ivay&) LLMsU_O_adgpaprK{G,r   c                 r    |j                         D ]#  }| j                  ||j                  |             % | S )a  Copies the extra fields of boxlist_to_copy_from to boxlist_to_copy_to.

    Args:
      boxlist_to_copy_to: BoxList to which extra fields are copied.
      boxlist_to_copy_from: BoxList from which fields are copied.

    Returns:
      boxlist_to_copy_to with extra fields.
    )r   r(   r*   )boxlist_to_copy_toboxlist_to_copy_fromr#   s      r   r   r     s@     &668 S$$U,@,J,J5,QRSr   c                 p    t        j                  |d d | f   d      }t        j                  |||k        S )Nr   rA   )r   r   r   )r   r   r   	thresholdmax_ious        r   0_update_valid_indices_by_removing_high_iou_boxesr     s4    ff)!-=*=>QGG>>.'Y*>??r   r!   )i'  r   g      $)T)r   )r<   numpyr   objectr   r?   rX   r_   rb   rd   ri   rn   rp   rr   r{   rf   r   r   r   r   r   r   r   r   r   r   r   r   r=   r   r   <module>r      s     df dN	E0,"& 
-
8
//"@ 1:0A0A 3>B?J@F4D,A:*Z7<8@r   