a
    yf6                     @   s   d dl mZ d dlmZ d dlZd dlZd dlm  m	Z
 d dlmZ d dlmZmZmZ d dlmZ d dlmZmZmZ d dlmZmZ G d	d
 d
eZdS )    )
ThreadPool)PathN)DetectionValidator)LOGGERNUM_THREADSops)check_requirements)SegmentMetricsbox_ioumask_iou)output_to_targetplot_imagesc                       s   e Zd ZdZd" fdd	Z fddZ fddZd	d
 Zdd Z fddZ	 fddZ
dd Zdd Zd#ddZdd Zdd Zdd Zdd Zd d! Z  ZS )$SegmentationValidatorai  
    A class extending the DetectionValidator class for validation based on a segmentation model.

    Example:
        ```python
        from ultralytics.models.yolo.segment import SegmentationValidator

        args = dict(model="yolov8n-seg.pt", data="coco8-seg.yaml")
        validator = SegmentationValidator(args=args)
        validator()
        ```
    Nc                    s>   t  ||||| d| _d| _d| j_t| j| jd| _	dS )zVInitialize SegmentationValidator and set task to 'segment', metrics to SegmentMetrics.Nsegment)save_diron_plot)
super__init__
plot_masksprocessargstaskr	   r   r   metrics)self
dataloaderr   Zpbarr   
_callbacks	__class__ _/var/www/html/django/DPS/env/lib/python3.9/site-packages/ultralytics/models/yolo/segment/val.pyr      s
    zSegmentationValidator.__init__c                    s(   t  |}|d | j |d< |S )zFPreprocesses batch by converting masks to float and sending to device.masks)r   
preprocesstodevicefloat)r   batchr   r   r   r!   '   s    z SegmentationValidator.preprocessc                    sZ   t  | g | _| jjr"td | jjs2| jjr8tjntj	| _
tg g g g g g d| _dS )zOInitialize metrics and select mask processing function based on save_json flag.pycocotools>=2.0.6)tp_mtpconfpred_cls
target_cls
target_imgN)r   init_metricsr   r   	save_jsonr   save_txtr   Zprocess_mask_nativeZprocess_maskr   dictstats)r   modelr   r   r   r-   -   s    z"SegmentationValidator.init_metricsc                 C   s   dd S )z5Return a formatted description of evaluation metrics.z,%22s%11s%11s%11s%11s%11s%11s%11s%11s%11s%11s)ClassZImagesZ	InstanceszBox(PRmAP50	mAP50-95)zMask(Pr4   r5   r6   r   )r   r   r   r   get_desc7   s    zSegmentationValidator.get_descc              
   C   sf   t j|d | jj| jj| jd| jjp*| jj| jj| j	d}t
|d dkrV|d d n|d }||fS )zIPost-processes YOLO predictions and returns output detections with proto.r   T)labelsZmulti_labelZagnosticmax_detnc      )r   Znon_max_suppressionr   r)   iouZlb
single_clsZagnostic_nmsr9   r:   len)r   predspprotor   r   r   postprocessG   s    
$z!SegmentationValidator.postprocessc                    s<   t  ||}| jjr|gn
|d |k}|d | |d< |S )LPrepares a batch for training or inference by processing images and targets.	batch_idxr    )r   _prepare_batchr   overlap_mask)r   sir%   Zprepared_batchZmidxr   r   r   rG   V   s    z$SegmentationValidator._prepare_batchc                    sL   t  ||}| j||ddddf |ddddf |d d}||fS )rE   N      Zimgsz)shape)r   _prepare_predr   )r   predpbatchrC   predn
pred_masksr   r   r   rM   ]   s    6z#SegmentationValidator._prepare_predc                 C   s  t t|d |d D ]\}\}}|  jd7  _t|}ttjd| jdtjd| jdtj|| jtj	| jdtj|| jtj	| jdd}| 
||}|d|d }	}
t|	}|	|d< |	 |d	< |dkr|r| j D ]}| j| ||  q| jjr| jjd
|
|	d q|d}| jjr:d|d
d
df< | |||\}}|d
d
df |d< |d
d
df |d< |r| ||
|	|d< | j||
|	||| jjdd|d< | jjr| j||
|	 | j D ]}| j| ||  qtj|tjd}| jjr*| jdk r*| j|d
d   | jjrx| ||d | tj |!ddd"  # |d |d | d | jj$r| %||| jj&|d | j'd t(|d | j) d  qd
S )zMetrics.r   r;   r#   )dtyper#   )r)   r*   r(   r'   clsbboxr+   r,   N)
detections	gt_bboxesgt_clsr       rK   r)   r*   r(   T)r    r'   rS   r<      im_file   Z	ori_shape	ratio_pad)r^   r8   z.txt)*	enumeratezipseenr@   r0   torchzerosr#   ZniouboolrG   popuniquer1   keysappendr   Zplotsconfusion_matrixZprocess_batchr?   rM   _process_batchrH   Z	as_tensoruint8Zbatch_ir   cpur.   pred_to_jsonr   Zscale_imageZpermute
contiguousnumpyr/   save_one_txt	save_confr   r   stem)r   rA   r%   rI   rN   rC   ZnprstatrO   rT   rU   nlkgt_masksrP   rQ   r   r   r   update_metricsc   sr    $







	 z$SegmentationValidator.update_metricsc                 O   s   | j | j_ | j| j_dS )z7Sets speed and confusion matrix for evaluation metrics.N)speedr   ri   )r   r   kwargsr   r   r   finalize_metrics   s    
z&SegmentationValidator.finalize_metricsFc                 C   s   |r|rNt |}tj||jd|ddd }	||dd}t||	kdd}|jdd |jdd krtj	|d |jdd dddd	 }|
d
}t||jd	 d||jd	 d}
nt||ddddf }
| |dddf ||
S )a  
        Compute correct prediction matrix for a batch based on bounding boxes and optional masks.

        Args:
            detections (torch.Tensor): Tensor of shape (N, 6) representing detected bounding boxes and
                associated confidence scores and class indices. Each row is of the format [x1, y1, x2, y2, conf, class].
            gt_bboxes (torch.Tensor): Tensor of shape (M, 4) representing ground truth bounding box coordinates.
                Each row is of the format [x1, y1, x2, y2].
            gt_cls (torch.Tensor): Tensor of shape (M,) representing ground truth class indices.
            pred_masks (torch.Tensor | None): Tensor representing predicted masks, if available. The shape should
                match the ground truth masks.
            gt_masks (torch.Tensor | None): Tensor of shape (M, H, W) representing ground truth masks, if available.
            overlap (bool): Flag indicating if overlapping masks should be considered.
            masks (bool): Flag indicating if the batch contains mask data.

        Returns:
            (torch.Tensor): A correct prediction matrix of shape (N, 10), where 10 represents different IoU levels.

        Note:
            - 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.

        Example:
            ```python
            detections = torch.tensor([[25, 30, 200, 300, 0.8, 1], [50, 60, 180, 290, 0.75, 0]])
            gt_bboxes = torch.tensor([[24, 29, 199, 299], [55, 65, 185, 295]])
            gt_cls = torch.tensor([1, 0])
            correct_preds = validator._process_batch(detections, gt_bboxes, gt_cls)
            ```
        rR   r;   g      ?g        NZbilinearF)modeZalign_cornersr   g      ?r=   rK   rY   )r@   rb   Zaranger#   viewrepeatwhererL   FZinterpolateZgt_r   r
   Zmatch_predictions)r   rV   rW   rX   rQ   rv   overlapr    rt   indexr>   r   r   r   rj      s    $
(z$SegmentationValidator._process_batchc                 C   sN   t |d |d |d d|d |d |d | jd| d	 | j| jd
	 dS )z2Plots validation samples with bounding box labels.imgrF   rT   r=   Zbboxesr    r\   	val_batchz_labels.jpg)r    pathsfnamenamesr   N)r   Zsqueezer   r   r   )r   r%   nir   r   r   plot_val_samples   s    z&SegmentationValidator.plot_val_samplesc                 C   sp   t |d gt|d ddt| jr4tj| jddn| jR |d | jd| d | j| jd	 | j	  d
S )z6Plots batch predictions with masks and bounding boxes.r   r   r[   )r9   )dimr\   r   z	_pred.jpg)r   r   r   r   N)
r   r   r@   r   rb   catr   r   r   clear)r   r%   rA   r   r   r   r   plot_predictions   s    	z&SegmentationValidator.plot_predictionsc                 C   sV   ddl m} |tj|d |d ftjdd| j|ddddf |dj||d dS )	zRSave YOLO detections to a txt file in normalized coordinates in a specific format.r   )Resultsr;   rZ   NrJ   )pathr   Zboxesr    )rq   )Zultralytics.engine.resultsr   nprc   rk   r   r/   )r   rP   rQ   rq   rL   filer   r   r   r   rp      s    z"SegmentationValidator.save_one_txtc              	      s&  ddl m   fdd}t|j}| r2t|n|}t|ddddf }|ddddf  |ddddf d 8  < t	|d}t
t}|||}	W d   n1 s0    Y  tt| | D ]J\}
\}}| j|| jt|d	  d
d |D t|d d	|	|
 d qdS )z
        Save one JSON result.

        Examples:
             >>> result = {"image_id": 42, "category_id": 18, "bbox": [258.15, 41.29, 348.26, 243.78], "score": 0.236}
        r   encodec                    s@    t j| dddddf dddd }|d d|d< |S )z:Encode predicted masks as RLE and append results to jdict.Nr   rk   )orderrS   r   countszutf-8)r   Zasarraydecode)xZrler   r   r   single_encode  s    *z9SegmentationValidator.pred_to_json.<locals>.single_encodeNrK   r]   )r]   r   r;   rY   c                 S   s   g | ]}t |d qS )r<   )round.0r   r   r   r   
<listcomp>      z6SegmentationValidator.pred_to_json.<locals>.<listcomp>)image_idZcategory_idrU   ZscoreZsegmentation)Zpycocotools.maskr   r   rr   	isnumericintr   Z	xyxy2xywhr   Z	transposer   r   mapr_   r`   tolistjdictrh   Z	class_mapr   )r   rP   filenamerQ   r   rr   r   boxpoolZrlesirB   br   r   r   rm     s$    
0
*"z"SegmentationValidator.pred_to_jsonc              
   C   s  | j jr~| jr~t| jr~| jd d }| jd }td| d| d zt	d dd	l
m} dd
lm} ||fD ]}| sxJ | dqx|t|}|t|}t|||d|||dgD ]x\}	}
| jrdd | jjjD |
j_|
  |
  |
  |	d d }|
jdd \|| jj|d  < || jj| < qW n6 ty| } ztd|  W Y d}~n
d}~0 0 |S )z6Return COCO-style object detection evaluation metrics.r   z"annotations/instances_val2017.jsonzpredictions.jsonz"
Evaluating pycocotools mAP using z and z...r&   r   )COCO)COCOevalz file not foundrU   Zsegmc                 S   s   g | ]}t t|jqS r   )r   r   rr   r   r   r   r   r   4  r   z3SegmentationValidator.eval_json.<locals>.<listcomp>rK   r]   Nr;   zpycocotools unable to run: )r   r.   Zis_cocor@   r   datar   r   infor   Zpycocotools.cocor   Zpycocotools.cocoevalr   is_filestrZloadResr_   r   ZdatasetZim_filesparamsZimgIdsevaluate
accumulateZ	summarizer1   r   rg   	Exceptionwarning)r   r1   Z	anno_jsonZ	pred_jsonr   r   r   annorN   r   evalidxer   r   r   	eval_json#  s2    
$*&zSegmentationValidator.eval_json)NNNNN)NNFF)__name__
__module____qualname____doc__r   r!   r-   r7   rD   rG   rM   rw   rz   rj   r   r   rp   rm   r   __classcell__r   r   r   r   r      s    
E
.!r   )Zmultiprocessing.poolr   pathlibr   ro   r   rb   Ztorch.nn.functionalnnZ
functionalr   Zultralytics.models.yolo.detectr   Zultralytics.utilsr   r   r   Zultralytics.utils.checksr   Zultralytics.utils.metricsr	   r
   r   Zultralytics.utils.plottingr   r   r   r   r   r   r   <module>   s   