
    h1,                        S SK Jr  S SKJr  S SKJr  S SKJr  S SKr	S SK
r
S SKJs  Jr  S SKJr  S SKJrJrJr  S SKJr  S S	KJrJr   " S
 S\5      rg)    )annotations)
ThreadPool)Path)AnyN)DetectionValidator)LOGGERNUM_THREADSops)check_requirements)SegmentMetricsmask_iouc                     ^  \ rS rSrSrSSU 4S jjjrSU 4S jjrSU 4S jjrSS jrSU 4S jjr	SU 4S jjr
SU 4S	 jjrSU 4S
 jjrSS jrSU 4S jjrSU 4S jjrSU 4S jjrSrU =r$ )SegmentationValidator   aY  
A class extending the DetectionValidator class for validation based on a segmentation model.

This validator handles the evaluation of segmentation models, processing both bounding box and mask predictions
to compute metrics such as mAP for both detection and segmentation tasks.

Attributes:
    plot_masks (list): List to store masks for plotting.
    process (callable): Function to process masks based on save_json and save_txt flags.
    args (namespace): Arguments for the validator.
    metrics (SegmentMetrics): Metrics calculator for segmentation tasks.
    stats (dict): Dictionary to store statistics during validation.

Examples:
    >>> from ultralytics.models.yolo.segment import SegmentationValidator
    >>> args = dict(model="yolo11n-seg.pt", data="coco8-seg.yaml")
    >>> validator = SegmentationValidator(args=args)
    >>> validator()
c                t   > [         TU ]  XX45        SU l        SU R                  l        [        5       U l        g)am  
Initialize SegmentationValidator and set task to 'segment', metrics to SegmentMetrics.

Args:
    dataloader (torch.utils.data.DataLoader, optional): Dataloader to use for validation.
    save_dir (Path, optional): Directory to save results.
    args (namespace, optional): Arguments for the validator.
    _callbacks (list, optional): List of callback functions.
Nsegment)super__init__processargstaskr   metrics)self
dataloadersave_dirr   
_callbacks	__class__s        ]/home/james-whalen/.local/lib/python3.13/site-packages/ultralytics/models/yolo/segment/val.pyr   SegmentationValidator.__init__(   s0     	t@"		%'    c                R   > [         TU ]  U5      nUS   R                  5       US'   U$ )z
Preprocess batch of images for YOLO segmentation validation.

Args:
    batch (dict[str, Any]): Batch containing images and annotations.

Returns:
    (dict[str, Any]): Preprocessed batch.
masks)r   
preprocessfloat)r   batchr   s     r   r#    SegmentationValidator.preprocess7   s/     "5)w--/gr    c                2  > [         TU ]  U5        U R                  R                  (       a  [	        S5        U R                  R                  (       d  U R                  R
                  (       a  [        R                  U l	        g[        R                  U l	        g)z
Initialize metrics and select mask processing function based on save_json flag.

Args:
    model (torch.nn.Module): Model to validate.
zfaster-coco-eval>=1.6.7N)
r   init_metricsr   	save_jsonr   save_txtr
   process_mask_nativeprocess_maskr   )r   modelr   s     r   r(   "SegmentationValidator.init_metricsE   sZ     	U#998926))2E2EI[I[s..adaqaqr    c                    SS-  $ )z5Return a formatted description of evaluation metrics.z,%22s%11s%11s%11s%11s%11s%11s%11s%11s%11s%11s)ClassImages	InstanceszBox(PRmAP50	mAP50-95)zMask(Pr3   r4   r5    )r   s    r   get_descSegmentationValidator.get_descR   s    $ )
 
 	
r    c                  > [        US   5      S:X  a  US   S   OUS   n[        TU ]	  US   5      nUR                  SS  Vs/ s H  nSU-  PM
     nn[	        U5       H  u  pVUR                  S5      nUR                  S   (       a  U R                  X%   XvS	   US
9O`[        R                  " S/U R                  [        R                  L a  UOUR                  SS Q7[        R                  US	   R                  S9US'   M     U$ s  snf )z
Post-process YOLO predictions and return output detections with proto.

Args:
    preds (list[torch.Tensor]): Raw predictions from the model.

Returns:
    list[dict[str, torch.Tensor]]: Processed detection predictions with masks.
      r      N   extrabboxes)shape)dtypedevicer"   )lenr   postprocessrA   	enumeratepopr   torchzerosr
   r+   uint8rC   )	r   predsprotoximgszipredcoefficientr   s	           r   rE   !SegmentationValidator.postprocessb   s    !$E!H 2aa#E!H- %AB01Q0 'GA((7+K $$Q' UX{N%P[[a4<<33J3J#J%PUP[P[\]\^P_a++>00 M (  1s   D
c                H  > [         T	U ]  X5      nUS   R                  S   nU R                  R                  (       aO  US   U   n[
        R                  " SUS-   UR                  S9R                  USS5      nXV:H  R                  5       nOUS   US   U:H     nU(       aw  US    Vs/ s H&  opR                  [        R                  L a  UOUS-  PM(     nnUR                  SS	 U:w  a.  [        R                  " US	   US
SS9S   nUR                  S5      nXSS'   U$ s  snf )a  
Prepare a batch for training or inference by processing images and targets.

Args:
    si (int): Batch index.
    batch (dict[str, Any]): Batch data containing images and annotations.

Returns:
    (dict[str, Any]): Prepared batch with processed annotations.
clsr   r"   r:   )rC   	batch_idxrN   r>   NbilinearF)modealign_cornersg      ?)r   _prepare_batchrA   r   overlap_maskrH   arangerC   viewr$   r   r
   r+   Finterpolategt_)
r   sir%   prepared_batchnlr"   indexs	mask_sizer   s
            r   rY   $SegmentationValidator._prepare_batch|   s     /:E"((+99!!'N2&ELLBF5<<@EEb!QOE^**,E'N5#5#;<E[ijq[rs[rVWllc.E.EE1PQ6Q[rIs{{12)+eDk9:]bcdef		#"'w ts   )-Dc                  > [         TU ]  X5      nUS   nUR                  S   S:X  d  US   R                  S   S:X  a6  [        R                  " US   R                  S   U R
                  4[        S9nOo[        US   R                  S5      US   R                  S5      R                  5       5      nU R                  US   XF5      R                  5       R                  5       nUR                  SU05        U$ )a  
Compute correct prediction matrix for a batch based on bounding boxes and optional masks.

Args:
    preds (dict[str, torch.Tensor]): Dictionary containing predictions with keys like 'cls' and 'masks'.
    batch (dict[str, Any]): Dictionary containing batch data with keys like 'cls' and 'masks'.

Returns:
    (dict[str, np.ndarray]): A dictionary containing correct prediction matrices including 'tp_m' for mask IoU.

Notes:
    - If `masks` is True, the function computes IoU between predicted and ground truth masks.
    - If `overlap` is True and `masks` is True, overlapping masks are taken into account when computing IoU.

Examples:
    >>> preds = {"cls": torch.tensor([1, 0]), "masks": torch.rand(2, 640, 640), "bboxes": torch.rand(2, 4)}
    >>> batch = {"cls": torch.tensor([1, 0]), "masks": torch.rand(2, 640, 640), "bboxes": torch.rand(2, 4)}
    >>> correct_preds = validator._process_batch(preds, batch)
rT   r   rB   r"   r:   tp_m)r   _process_batchrA   nprI   niouboolr   flattenr$   match_predictionscpunumpyupdate)r   rK   r%   tpgt_clsri   iour   s          r   rj   $SegmentationValidator._process_batch   s    ( W#E1u<<?a5<#5#5a#8A#=88U5\//2DII>dKD5>11!4eGn6L6LQ6O6U6U6WXC))%,DHHJPPRD
		64.!	r    c                  > U H  nUS   nUR                   S   U R                  R                  :  a.  [        R                  " SU R                  R                   S35        [
        R                  " USU R                  R                   [
        R                  S9R                  5       US'   M     [        TU ])  XX0R                  R                  S9  g)z
Plot batch predictions with masks and bounding boxes.

Args:
    batch (dict[str, Any]): Batch containing images and annotations.
    preds (list[dict[str, torch.Tensor]]): List of predictions from the model.
    ni (int): Batch index.
r"   r   z&Limiting validation plots to 'max_det=z' items.Nrh   )max_det)rA   r   rx   r   warningrH   	as_tensorrJ   rp   r   plot_predictions)r   r%   rK   nipr"   r   s         r   r{   &SegmentationValidator.plot_predictions   s     AgJE{{1~		 1 11!G		HYHYGZZbcd/B1B1B)C5;;W[[]AgJ	 
 	 r99;L;L Mr    c                f   SSK Jn  U" [        R                  " US   US   4[        R                  S9SU R
                  [        R                  " US   US   R                  S5      US	   R                  S5      /SS
9[        R                  " US   [        R                  S9S9R                  XBS9  g)aT  
Save YOLO detections to a txt file in normalized coordinates in a specific format.

Args:
    predn (torch.Tensor): Predictions in the format (x1, y1, x2, y2, conf, class).
    save_conf (bool): Whether to save confidence scores.
    shape (tuple[int, int]): Shape of the original image.
    file (Path): File path to save the detections.
r   )Resultsr:   rh   Nr@   confr<   rT   )dimr"   )pathnamesboxesr"   )	save_conf)ultralytics.engine.resultsr   rk   rI   rJ   r   rH   cat	unsqueezerz   r*   )r   prednr   rA   filer   s         r   save_one_txt"SegmentationValidator.save_one_txt   s     	7HHeAha):**))U8_eFm.E.Eb.I5QV<KaKabdKeflmn//%.D	
 (4(
-r    c                J  >^	 SSK Jm	  U	4S jn[        R                  " US   S5      n[	        [
        5       nUR                  X45      nSSS5        [        T
U ]!  X5        [        W5       H#  u  pxXR                  [        U5      * U-      S'   M%     g! , (       d  f       NP= f)a  
Save one JSON result for COCO evaluation.

Args:
    predn (dict[str, torch.Tensor]): Predictions containing bboxes, masks, confidence scores, and classes.
    pbatch (dict[str, Any]): Batch dictionary containing 'imgsz', 'ori_shape', 'ratio_pad', and 'im_file'.
r   )encodec                   > T" [         R                  " U SS2SS2S4   SSS95      S   nUS   R                  S5      US'   U$ )z:Encode predicted masks as RLE and append results to jdict.Nr]   rJ   )orderrB   r   countszutf-8)rk   asarraydecode)rM   rler   s     r   single_encode9SegmentationValidator.pred_to_json.<locals>.single_encode   sF    AaDjMGLMaPCM009CMJr    r"   )r=   r   r:   Nsegmentation)faster_coco_eval.core.maskr   rk   	transposer   r	   mapr   pred_to_jsonrF   jdictrD   )r   r   pbatchr   
pred_maskspoolrlesrO   rr   r   s            @r   r   "SegmentationValidator.pred_to_json   s     	6	 \\%.)<
$88M6D %U+dODA9:JJD	zA~&~6 $ %$s   B
B"c           	        > 0 [         TU ]  X5      ES[        R                  " [        R
                  " US   [        R                  S9R                  SSS5      R                  5       R                  5       R                  5       US   US   S90E$ )	z.Scales predictions to the original image size.r"   rh   r:   r=   r   	ori_shape	ratio_pad)r   )r   scale_predsr
   scale_imagerH   rz   rJ   permute
contiguousrp   rq   )r   r   r   r   s      r   r   !SegmentationValidator.scale_preds   s    
g!%0
S__gekkBJJ1aQRS^^`ddflln{# -
 	
r    c                   > U R                   S-  nU R                  S   S-  U R                  (       a  SOSU R                  R                   S3-  n[
        TU ]  XUSS/S	S
/S9$ )z;Return COCO-style instance segmentation evaluation metrics.zpredictions.jsonr   r   zinstances_val2017.jsonlvis_v1_z.jsonbboxsegmBoxMask)suffix)r   datais_cocor   splitr   coco_evaluate)r   stats	pred_json	anno_jsonr   s       r   	eval_jsonSegmentationValidator.eval_json   sw    MM$66	IIf+/<<'x		GXX]=^` 	
 w$Uy66BR\aci[j$kkr    )r   r   )NNNN)returnNone)r%   dict[str, Any]r   r   )r-   ztorch.nn.Moduler   r   )r   str)rK   zlist[torch.Tensor]r   list[dict[str, torch.Tensor]])r`   intr%   r   r   r   )rK   dict[str, torch.Tensor]r%   r   r   zdict[str, np.ndarray])r%   r   rK   r   r|   r   r   r   )
r   ztorch.Tensorr   rm   rA   ztuple[int, int]r   r   r   r   )r   r   r   r   r   r   )r   r   r   r   r   r   )r   r   r   r   )__name__
__module____qualname____firstlineno____doc__r   r#   r(   r7   rE   rY   rj   r{   r   r   r   r   __static_attributes____classcell__)r   s   @r   r   r      sR    (( (r
 46<N .(;.	
l lr    r   )
__future__r   multiprocessing.poolr   pathlibr   typingr   rq   rk   rH   torch.nn.functionalnn
functionalr]   ultralytics.models.yolo.detectr   ultralytics.utilsr   r	   r
   ultralytics.utils.checksr   ultralytics.utils.metricsr   r   r   r6   r    r   <module>r      s?    # +       = 6 6 7 >pl. plr    