a
    yf"                     @   s|  d dl Z d dlmZ d dlmZmZmZmZ d dlZ	d dl
Z
d'e
jee ee ee
jdddZeeee ddf dd	d
Ze
jeee
jdddZee	jdddZeeeee	j dddZeedf eeeeee  ee f dddZe
jee e
jdddZe
jee e
jdddZe
jee eee
jddd Ze	jeeee	jef d!d"d#Ze
je
jd$d%d&ZdS )(    N)product)Any	GeneratorListTuple      4@)boxescrop_boxorig_boxatolreturnc                 C   s   t j|t j| jd}t j|t j| jd}t| | } t j| |dddf |dd}t j| |dddf |dd}t || }t j|ddS )zeDetermines if bounding boxes are near the edge of a cropped image region using a specified tolerance.)dtypedeviceNr   )r   Zrtol   dim)torchZ	as_tensorfloatr   uncrop_boxes_xyxyiscloselogical_andany)r   r	   r
   r   Zcrop_box_torchZorig_box_torchZnear_crop_edgeZnear_image_edge r   V/var/www/html/django/DPS/env/lib/python3.9/site-packages/ultralytics/models/sam/amg.pyis_box_near_crop_edge   s    r   )
batch_sizer   c                 '   sr    rt  fdd D s"J dt d  tt d  dk }t|D ]fdd D V  qRdS )z_Yields batches of data from input arguments with specified batch size for efficient processing.c                 3   s"   | ]}t |t  d  kV  qdS )r   N)len).0a)argsr   r   	<genexpr>       z!batch_iterator.<locals>.<genexpr>z-Batched iteration must have same-size inputs.r   c                    s$   g | ]}|   d    qS r   r   )r   arg)br   r   r   
<listcomp>   r!   z"batch_iterator.<locals>.<listcomp>N)allr   intrange)r   r   Z	n_batchesr   )r   r$   r   r   batch_iterator   s    "(r)   )masksmask_thresholdthreshold_offsetr   c                 C   sP   | || kj dtjdj dtjd}| || kj dtjdj dtjd}|| S )a  
    Computes the stability score for a batch of masks.

    The stability score is the IoU between binary masks obtained by thresholding the predicted mask logits at
    high and low values.

    Args:
        masks (torch.Tensor): Batch of predicted mask logits.
        mask_threshold (float): Threshold value for creating binary masks.
        threshold_offset (float): Offset applied to the threshold for creating high and low binary masks.

    Returns:
        (torch.Tensor): Stability scores for each mask in the batch.

    Notes:
        - One mask is always contained inside the other.
        - Memory is saved by preventing unnecessary cast to torch.int64.

    Examples:
        >>> masks = torch.rand(10, 256, 256)  # Batch of 10 masks
        >>> mask_threshold = 0.5
        >>> threshold_offset = 0.1
        >>> stability_scores = calculate_stability_score(masks, mask_threshold, threshold_offset)
    )r   )sumr   Zint16Zint32)r*   r+   r,   ZintersectionsZunionsr   r   r   calculate_stability_score    s    $$r/   )
n_per_sider   c                 C   sp   dd|   }t |d| | }t |dddf | df}t |dddf d| f}t j||gddddS )zaGenerate a 2D grid of evenly spaced points in the range [0,1]x[0,1] for image segmentation tasks.r      Nr-   )Zaxis)npZlinspaceZtilestackreshape)r0   offsetZpoints_one_sideZpoints_xZpoints_yr   r   r   build_point_grid>   s
    r6   )r0   n_layersscale_per_layerr   c                    s    fddt |d D S )zQGenerates point grids for multiple crop layers with varying scales and densities.c                    s    g | ]}t t |  qS r   )r6   r'   r   ir0   r8   r   r   r%   I   r!   z/build_all_layer_point_grids.<locals>.<listcomp>r   )r(   )r0   r7   r8   r   r;   r   build_all_layer_point_gridsG   s    r<   .)im_sizer7   overlap_ratior   c                    s
  g g  }}| \}}t ||}|dd||g |d dd }t|D ]}	d|	d  }
t|| d|
  |||
|||
 fddt|
D } fddt|
D }t||D ]@\}}||t | |t |  |g}|| ||	d  qqH||fS )	ziGenerates crop boxes of varying sizes for multi-scale image processing, with layered overlapping regions.r   c                 S   s   t t||d  |  | S )z4Crops bounding boxes to the size of the input image.r   )r'   mathceil)Zorig_lenZn_cropsoverlapr   r   r   crop_lenX   s    z%generate_crop_boxes.<locals>.crop_lenr1   r   c                    s   g | ]}t   | qS r   r'   r9   )crop_wrA   r   r   r%   c   r!   z'generate_crop_boxes.<locals>.<listcomp>c                    s   g | ]}t   | qS r   rC   r9   )crop_hrA   r   r   r%   d   r!   )minappendr(   r'   r   )r=   r7   r>   Z
crop_boxesZ
layer_idxsZim_hZim_wZ
short_siderB   Zi_layerZn_crops_per_sideZcrop_box_x0Zcrop_box_y0x0y0boxr   )rE   rD   rA   r   generate_crop_boxesL   s$    


 
rK   )r   r	   r   c                 C   sF   |\}}}}t j||||gg| jd}t| jdkr>|d}| | S )zIUncrop bounding boxes by adding the crop box offset to their coordinates.r      r   r   Ztensorr   r   shape	unsqueeze)r   r	   rH   rI   _r5   r   r   r   r   o   s
    
r   )pointsr	   r   c                 C   sB   |\}}}}t j||gg| jd}t| jdkr:|d}| | S )zAUncrop points by adding the crop box offset to their coordinates.rL   rM   r   rN   )rR   r	   rH   rI   rQ   r5   r   r   r   uncrop_pointsy   s
    
rS   )r*   r	   orig_horig_wr   c                 C   sr   |\}}}}|dkr0|dkr0||kr0||kr0| S |||  |||   }}	||| ||	| f}
t jjj| |
ddS )z]Uncrop masks by padding them to the original image size, handling coordinate transformations.r   )value)r   nnZ
functionalpad)r*   r	   rT   rU   rH   rI   x1y1Zpad_xZpad_yrX   r   r   r   uncrop_masks   s     r[   )maskarea_threshmoder   c                    s   ddl }|dv s J d| d|dk}|| A tj}||d\}}}}	|dddf d	d }
 fd
dt|
D }|s| dfS dg| |sfddt|D ptt|
d	 gt	|} | dfS )zWRemoves small disconnected regions or holes in a mask based on area threshold and mode.r   N>   holesZislandszProvided mode z is invalidr_      r-   r   c                    s    g | ]\}}| k r|d  qS r"   r   )r   r:   s)r]   r   r   r%      r!   z(remove_small_regions.<locals>.<listcomp>Fc                    s   g | ]}| vr|qS r   r   r9   )fill_labelsr   r   r%      r!   T)
cv2Zastyper2   Zuint8ZconnectedComponentsWithStats	enumerater(   r'   Zargmaxisin)r\   r]   r^   rc   Zcorrect_holesZworking_maskZn_labelsZregionsstatsrQ   sizesZsmall_regionsr   )r]   rb   r   remove_small_regions   s    
*rh   )r*   r   c                 C   s  t | dkr4t jg | jdd dR d| jiS | j}|dd \}}t|dkrb| ddn| d} t j| dd	\}}|t j	||jd
dddf  }t j|dd	\}}|||   }t j
|dd	\}}t j| dd	\}	}|	t j	||	jd
dddf  }
t j|
dd	\}}|
||	   }
t j
|
dd	\}}||k ||k B }t j||||gdd	}|| d }t|dkr|jg |dd dR  S |d S )zlCalculates bounding boxes in XYXY format around binary masks, handling empty masks and various input shapes.r   N   r   r1   r-   r   rL   )r   ZnumelZzerosrO   r   r   flattenrP   maxZarangerF   r3   r4   )r*   rO   hwZ	in_heightrQ   Zin_height_coordsZbottom_edgesZ	top_edgesZin_widthZin_width_coordsZright_edgesZ
left_edgesZempty_filteroutr   r   r   batched_mask_to_box   s&    &"  rq   )r   )r?   	itertoolsr   typingr   r   r   r   numpyr2   r   ZTensorr'   r   r   r)   r/   Zndarrayr6   r<   rK   r   rS   r[   strboolrh   rq   r   r   r   r   <module>   s*    	#

 