
    |hP                         d dl Z d dlmZ d dlmZmZmZmZmZm	Z	 d dl
Zd dlZd dlmZmZmZ d dlmZ d dlmZmZ d dlmZ d dlmZmZmZ d d	lmZ  G d
 de      Zy)    N)Path)AnyDictListOptionalTupleUnion)build_dataloaderbuild_yolo_dataset	converter)BaseValidator)LOGGERops)check_requirements)ConfusionMatrix
DetMetricsbox_iou)plot_imagesc                   ,    e Zd ZdZd.d/ fdZdeeef   deeef   fdZde	j                  j                  ddfdZdefd	Zd
e	j                  deeee	j                  f      fdZdedeeef   deeef   fdZdeee	j                  f   deeef   deee	j                  f   fdZd
eeee	j                  f      deeef   ddfdZd/dZdeeef   fdZd/dZd
eee	j                  f   deeef   deeej2                  f   fdZd0dededee   de	j8                  j:                  j<                  fdZdedede	j8                  j:                  j@                  fdZ!deeef   deddfdZ"	 d1deeef   d
eeee	j                  f      dedee   ddf
dZ#d eee	j                  f   d!e$d"e%eef   d#e&ddf
d$Z'd eee	j                  f   d%eddfd&Z(d'eeef   deeef   fd(Z)	 	 d2d'eeef   d)ed*ed+e*eee   f   d,e*eee   f   deeef   fd-Z+ xZ,S )3DetectionValidatora~  
    A class extending the BaseValidator class for validation based on a detection model.

    This class implements validation functionality specific to object detection tasks, including metrics calculation,
    prediction processing, and visualization of results.

    Attributes:
        is_coco (bool): Whether the dataset is COCO.
        is_lvis (bool): Whether the dataset is LVIS.
        class_map (List[int]): Mapping from model class indices to dataset class indices.
        metrics (DetMetrics): Object detection metrics calculator.
        iouv (torch.Tensor): IoU thresholds for mAP calculation.
        niou (int): Number of IoU thresholds.
        lb (List[Any]): List for storing ground truth labels for hybrid saving.
        jdict (List[Dict[str, Any]]): List for storing JSON detection results.
        stats (Dict[str, List[torch.Tensor]]): Dictionary for storing statistics during validation.

    Examples:
        >>> from ultralytics.models.yolo.detect import DetectionValidator
        >>> args = dict(model="yolo11n.pt", data="coco8.yaml")
        >>> validator = DetectionValidator(args=args)
        >>> validator()
    Nreturnc                 
   t         |   ||||       d| _        d| _        d| _        d| j
                  _        t        j                  ddd      | _	        | j                  j                         | _        t               | _        y)a  
        Initialize detection validator with necessary variables and settings.

        Args:
            dataloader (torch.utils.data.DataLoader, optional): Dataloader to use for validation.
            save_dir (Path, optional): Directory to save results.
            args (Dict[str, Any], optional): Arguments for the validator.
            _callbacks (List[Any], optional): List of callback functions.
        FNdetectg      ?gffffff?
   )super__init__is_cocois_lvis	class_mapargstasktorchlinspaceiouvnumelniour   metrics)self
dataloadersave_dirr    
_callbacks	__class__s        a/var/www/html/test/engine/venv/lib/python3.12/site-packages/ultralytics/models/yolo/detect/val.pyr   zDetectionValidator.__init__+   sg     	XtZ@!		NN3b1	IIOO%	!|    batchc                     |d   j                  | j                  d      |d<   | j                  j                  r|d   j                         n|d   j	                         dz  |d<   dD ]#  }||   j                  | j                        ||<   % |S )z
        Preprocess batch of images for YOLO validation.

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

        Returns:
            (Dict[str, Any]): Preprocessed batch.
        imgT)non_blocking   >   clsbboxes	batch_idx)todevicer    halffloat)r(   r/   ks      r-   
preprocesszDetectionValidator.preprocess>   s     U|t{{Fe/3yy~~e))+5<CUCUCW[^^e/ 	0AQx{{4;;/E!H	0 r.   modelc                 
   | j                   j                  | j                  j                  d      }t	        |t
              xrL d|v xrF |j                  t        j                   d      xs" |j                  t        j                   d      | _	        t	        |t
              xr d|v xr | j                   | _
        | j                  rt        j                         n*t        t        dt        |j                         dz               | _        | j                  xj$                  | j                  j&                  xr) | j                  xs | j                  xr | j(                   z  c_        |j                   | _        t        |j                         | _        t-        |dd      | _        d	| _        g | _        | j                   | j4                  _        t7        t        |j                   j9                               
      | _        y)z
        Initialize evaluation metrics for YOLO detection validation.

        Args:
            model (torch.nn.Module): Model to validate.
         cocozval2017.txtztest-dev2017.txtlvis   end2endFr   )namesN)datagetr    split
isinstancestrendswithossepr   r   r   coco80_to_coco91_classlistrangelenrD   r   	save_jsonvaltrainingncgetattrrC   seenjdictr'   r   valuesconfusion_matrix)r(   r=   rR   s      r-   init_metricszDetectionValidator.init_metricsO   sz    iimmDIIOOR0sC  d#d45bP`Fa9b 	
 "#s+R#RdllBR?C||99;QUV[\]_bchcncn_ors_sVtQu		tyy}}e$,,2N$,,eX\XeXeTee[[
ekk"ui7	
!ZZ /d5;;;M;M;O6P Qr.   c                     ddz  S )zBReturn a formatted string summarizing class metrics of YOLO model.z%22s%11s%11s%11s%11s%11s%11s)ClassImages	InstanceszBox(PRmAP50z	mAP50-95) r(   s    r-   get_desczDetectionValidator.get_descg   s    #'kkkr.   predsc                    t        j                  || j                  j                  | j                  j                  | j                  j
                  dk(  rdn| j                  d| j                  j                  xs | j                  j                  | j                  j                  | j                  | j                  j
                  dk(  	      }|D cg c])  }|ddddf   |dddf   |dddf   |ddd	df   d
+ c}S c c}w )aN  
        Apply Non-maximum suppression to prediction outputs.

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

        Returns:
            (List[Dict[str, torch.Tensor]]): Processed predictions after NMS, where each dict contains
                'bboxes', 'conf', 'cls', and 'extra' tensors.
        r   r   Tobb)rT   multi_labelagnosticmax_detrC   rotatedN         )r5   confr4   extra)r   non_max_suppressionr    rn   iour!   rT   
single_clsagnostic_nmsri   rC   )r(   rd   outputsxs       r-   postprocesszDetectionValidator.postprocessk   s     ))IINNIIMMIINNh.qDGGYY))CTYY-C-CII%%LLIINNe+

 cjj]^1QU8Qq!tWQq!tWqQRTUTVQVxXjjjs   .Dsic                 d   |d   |k(  }|d   |   j                  d      }|d   |   }|d   |   }|d   j                  dd }|d	   |   }t        |      rUt        j                  |      t        j                  || j                  
      g d   z  }t        j                  ||||       |||||dS )a*  
        Prepare a batch of images and annotations for validation.

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

        Returns:
            (Dict[str, Any]): Prepared batch with processed annotations.
        r6   r4   r5   	ori_shaper1      N	ratio_pad)r8   )rB   r   rB   r   r|   )r4   r5   rz   imgszr|   )	squeezeshaperP   r   	xywh2xyxyr"   tensorr8   scale_boxes)	r(   rw   r/   idxr4   bboxrz   r~   r|   s	            r-   _prepare_batchz!DetectionValidator._prepare_batch   s     K B&El3''+Xs#+&r*	e""12&+&r*	s8==&eDKK)PQ])^^DOOE4iHdUajkkr.   predpbatchc                     |d   }| j                   j                  r|dz  }t        j                  |d   |d   j	                         |d   |d         }||d   |d	S )
aP  
        Prepare predictions for evaluation against ground truth.

        Args:
            pred (Dict[str, torch.Tensor]): Post-processed predictions from the model.
            pbatch (Dict[str, Any]): Prepared batch information.

        Returns:
            (Dict[str, torch.Tensor]): Prepared predictions in native space.
        r4   r   r~   r5   rz   r|   r}   rn   )r5   rn   r4   )r    rr   r   r   clone)r(   r   r   r4   r5   s        r-   _prepare_predz DetectionValidator._prepare_pred   sj     5k991HC7OT(^113VK5HTZ[fTg
 !$v,sCCr.   c                 <   t        |      D ]  \  }}| xj                  dz  c_        | j                  ||      }| j                  ||      }|d   j	                         j                         }t        |d         dk(  }| j                  j                  i | j                  ||      |t        j                  |      |rt        j                  d      n |d   j	                         j                         |rt        j                  d      n |d   j	                         j                         d       | j                  j                  r2| j                  j!                  ||| j                  j"                         |rq| j                  j$                  r| j'                  ||d   |          | j                  j(                  s| j+                  || j                  j,                  |d   | j.                  d	z  t1        |d   |         j2                   d
z          y)z
        Update metrics with new predictions and ground truth.

        Args:
            preds (List[Dict[str, torch.Tensor]]): List of predictions from the model.
            batch (Dict[str, Any]): Batch data containing ground truth.
        rB   r4   r   rn   )
target_cls
target_imgrn   pred_cls)rn   im_filerz   labelsz.txtN)	enumeraterV   r   r   cpunumpyrP   r'   update_stats_process_batchnpuniquezerosr    plotsrY   process_batchrn   rQ   pred_to_jsonsave_txtsave_one_txt	save_confr*   r   stem)	r(   rd   r/   rw   r   r   prednr4   no_preds	            r-   update_metricsz!DetectionValidator.update_metrics   s    "%(  	HBIINI((U3F&&tV4E-##%++-C%,'1,GLL%%))%8"%"$))C.+2BHHQKf8I8I8K8Q8Q8S/6E%L<L<L<N<T<T<V yy%%33E6		3W yy""!!%y)9")=>yy!!!!II'';'MMH,$uY7G7K2L2Q2Q1RRV/WW	7 	r.   c                 D   | j                   j                  r9dD ]4  }| j                  j                  | j                  || j
                         6 | j                  | j                  _        | j                  | j                  _        | j                  | j                  _        y)z8Set final values for metrics speed and confusion matrix.)TF)r*   	normalizeon_plotN)r    r   rY   plotr*   r   speedr'   )r(   r   s     r-   finalize_metricsz#DetectionValidator.finalize_metrics   sv    99??( n	%%**DMMY`d`l`l*mn!ZZ(,(=(=% $r.   c                     | j                   j                  | j                  | j                  j                  | j
                         | j                   j                          | j                   j                  S )z
        Calculate and return metrics statistics.

        Returns:
            (Dict[str, Any]): Dictionary containing metrics results.
        )r*   r   r   )r'   processr*   r    r   r   clear_statsresults_dictrb   s    r-   	get_statszDetectionValidator.get_stats   sP     	dmm$))//SWS_S_`  "||(((r.   c                    ddt        | j                  j                        z  z   }t        j                  |d| j
                  | j                  j                  j                         g| j                  j                         z         | j                  j                  j                         dk(  r-t        j                  d| j                  j                   d       | j                  j                  r| j                  s| j                  dkD  rt        | j                  j                        rt!        | j                  j"                        D ]w  \  }}t        j                  || j$                  |   | j                  j&                  |   | j                  j                  |   g| j                  j)                  |      z         y yyyyy)	z0Print training/validation set metrics per class.z%22s%11i%11iz%11.3gallr   zno labels found in z, set, can not compute metrics without labelsrB   N)rP   r'   keysr   inforV   nt_per_classsummean_resultswarningr    r!   verboserS   rT   statsr   ap_class_indexrD   nt_per_imageclass_result)r(   pfics       r-   print_resultsz DetectionValidator.print_results   s]    8c$,,2C2C.D#DDB%DLL,E,E,I,I,KjdllNgNgNijjk<<$$((*a/NN00@@lmn 99T]]tww{s4<<K]K]G^!$,,"="=> 	1

111!411!4 2215		 H_{]r.   c                 B   t        |d         dk(  st        |d         dk(  r5dt        j                  t        |d         | j                  ft              iS t        |d   |d         }d| j                  |d   |d   |      j                         j                         iS )a  
        Return correct prediction matrix.

        Args:
            preds (Dict[str, torch.Tensor]): Dictionary containing prediction data with 'bboxes' and 'cls' keys.
            batch (Dict[str, Any]): Batch dictionary containing ground truth data with 'bboxes' and 'cls' keys.

        Returns:
            (Dict[str, np.ndarray]): Dictionary containing 'tp' key with correct prediction matrix of shape (N, 10) for 10 IoU levels.
        r4   r   tpdtyper5   )	rP   r   r   r&   boolr   match_predictionsr   r   )r(   rd   r/   rq   s       r-   r   z!DetectionValidator._process_batch   s     uU|!Su%6!%;"((Ce$5tyy#ANOOeHouX7d,,U5\5<MQQSYY[\\r.   img_pathmodec                 `    t        | j                  ||| j                  || j                        S )al  
        Build YOLO Dataset.

        Args:
            img_path (str): Path to the folder containing images.
            mode (str): `train` mode or `val` mode, users are able to customize different augmentations for each mode.
            batch (int, optional): Size of batches, this is for `rect`.

        Returns:
            (Dataset): YOLO dataset.
        )r   stride)r   r    rE   r   )r(   r   r   r/   s       r-   build_datasetz DetectionValidator.build_dataset  s(     "$))Xudiid[_[f[fggr.   dataset_path
batch_sizec                 r    | j                  ||d      }t        ||| j                  j                  dd      S )a   
        Construct and return dataloader.

        Args:
            dataset_path (str): Path to the dataset.
            batch_size (int): Size of each batch.

        Returns:
            (torch.utils.data.DataLoader): Dataloader for validation.
        rR   )r/   r   Fry   )shufflerank)r   r
   r    workers)r(   r   r   datasets       r-   get_dataloaderz!DetectionValidator.get_dataloader  s:     $$\%$PTYY5F5FPU\^__r.   nic                 t    t        ||d   | j                  d| dz  | j                  | j                         y)z
        Plot validation image samples.

        Args:
            batch (Dict[str, Any]): Batch containing images and annotations.
            ni (int): Batch index.
        r   	val_batchz_labels.jpg)r   pathsfnamerD   r   N)r   r*   rD   r   )r(   r/   r   s      r-   plot_val_samplesz#DetectionValidator.plot_val_samples+  s:     		"--IbT"==**LL	
r.   ri   c                    t        |      D ]#  \  }}t        j                  |d         |z  |d<   % |d   j                         }|xs | j                  j
                  }|D 	ci c].  }|t        j                  |D 	cg c]
  }	|	|   d|  c}	d      0 }
}}	t        j                  |
d   ddddf         |
d   ddddf<   t        |d   |
|d	   | j                  d
| dz  | j                  | j                         yc c}	w c c}	}w )au  
        Plot predicted bounding boxes on input images and save the result.

        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.
            max_det (Optional[int]): Maximum number of detections to plot.
        rn   r6   r   Ndimr5   rk   r1   r   r   z	_pred.jpg)imagesr   r   r   rD   r   )r   r"   	ones_liker   r    ri   catr   	xyxy2xywhr   r*   rD   r   )r(   r/   rd   r   ri   r   r   r   r;   ru   batched_predss              r-   plot_predictionsz#DetectionValidator.plot_predictions;  s    !' 	BGAt %V = AD	BQx}}.TYY..W[\RSEIIu&E!qtHW~&E1MM\\),}X7NqRTSTRTu7U)Vh2A2&< 	"--IbT";;**LL	
 'F\s   $D	=DD	D	r   r   r   filec                 2   ddl m}  |t        j                  |d   |d   ft        j                        d| j
                  t        j                  |d   |d   j                  d      |d	   j                  d      gd
            j                  ||       y)a  
        Save YOLO detections to a txt file in normalized coordinates in a specific format.

        Args:
            predn (Dict[str, torch.Tensor]): Dictionary containing predictions with keys 'bboxes', 'conf', and 'cls'.
            save_conf (bool): Whether to save confidence scores.
            shape (Tuple[int, int]): Shape of the original image (height, width).
            file (Path): File path to save the detections.
        r   )ResultsrB   r   Nr5   rn   ry   r4   r   )pathrD   boxes)r   )
ultralytics.engine.resultsr   r   r   uint8rD   r"   r   	unsqueezer   )r(   r   r   r   r   r   s         r-   r   zDetectionValidator.save_one_txtX  s     	7HHeAha):**))U8_eFm.E.Eb.I5QV<KaKabdKeflmn		

 (49(
-r.   filenamec                    t        |      j                  }|j                         rt        |      n|}t	        j
                  |d         }|ddddfxx   |ddddf   dz  z  cc<   t        |j                         |d   j                         |d   j                               D ]^  \  }}}| j                  j                  || j                  t        |         |D 	cg c]  }	t        |	d       c}	t        |d      d       ` yc c}	w )	aE  
        Serialize YOLO predictions to COCO json format.

        Args:
            predn (Dict[str, torch.Tensor]): Predictions dictionary containing 'bboxes', 'conf', and 'cls' keys
                with bounding box coordinates, confidence scores, and class predictions.
            filename (str): Image filename.
        r5   Nr{   rn   r4      rl   )image_idcategory_idr   score)r   r   	isnumericintr   r   ziptolistrW   appendr   round)
r(   r   r   r   r   boxbsr   ru   s
             r-   r   zDetectionValidator.pred_to_jsonk  s     H~"" $ 03t9dmmE(O,ArrE
c!QR%j1n$
3::<v)=)=)?uATATAVW 	GAq!JJ (#'>>#a&#9234QU1a[4"1a[		
 5s   D	r   c                     | j                   dz  }| j                  d   dz  | j                  rdnd| j                  j                   dz  }| j                  |||      S )a  
        Evaluate YOLO output in JSON format and return performance statistics.

        Args:
            stats (Dict[str, Any]): Current statistics dictionary.

        Returns:
            (Dict[str, Any]): Updated statistics dictionary with COCO/LVIS evaluation results.
        zpredictions.jsonr   annotationszinstances_val2017.jsonlvis_v1_z.json)r*   rE   r   r    rG   coco_evaluate)r(   r   	pred_json	anno_jsons       r-   	eval_jsonzDetectionValidator.eval_json  sh     MM$66	IIf+/<<'x		GXX]=^` 	
 !!%I>>r.   r   r   	iou_typessuffixc           	      
   | j                   j                  r7| j                  s| j                  rt	        | j
                        rt        j                  d| d| d       	 ||fD ]  }|j                         rJ | d        t        |t              r|gn|}t        |t              r|gn|}t        d       ddlm}m}  ||      }	|	j                  |      }
t!        |      D ]M  \  }} ||	|
|| j                  t        j                        }| j"                  j$                  j&                  D cg c]   }t)        t+        |      j,                        " c}|j.                  _        |j3                          |j5                          |j7                          |j8                  d	   |d
||   d    d<   |j8                  d   |d||   d    d<   | j                  s|j8                  d   |d||   d    d<   |j8                  d   |d||   d    d<   |j8                  d   |d||   d    d<   P | j                  r|d   |d<   |S |S c c}w # t:        $ r#}t        j<                  d|        Y d}~|S d}~ww xY w)az  
        Evaluate COCO/LVIS metrics using faster-coco-eval library.

        Performs evaluation using the faster-coco-eval library to compute mAP metrics
        for object detection. Updates the provided stats dictionary with computed metrics
        including mAP50, mAP50-95, and LVIS-specific metrics if applicable.

        Args:
            stats (Dict[str, Any]): Dictionary to store computed metrics and statistics.
            pred_json (str | Path]): Path to JSON file containing predictions in COCO format.
            anno_json (str | Path]): Path to JSON file containing ground truth annotations in COCO format.
            iou_types (str | List[str]]): IoU type(s) for evaluation. Can be single string or list of strings.
                Common values include "bbox", "segm", "keypoints". Defaults to "bbox".
            suffix (str | List[str]]): Suffix to append to metric names in stats dictionary. Should correspond
                to iou_types if multiple types provided. Defaults to "Box".

        Returns:
            (Dict[str, Any]): Updated stats dictionary containing the computed COCO/LVIS evaluation metrics.
        z'
Evaluating faster-coco-eval mAP using z and z...z file not foundzfaster-coco-eval>=1.6.7r   )COCOCOCOeval_faster)iouType
lvis_styleprint_functionAP_allzmetrics/mAP50()AP_50zmetrics/mAP50-95(APrzmetrics/APr(APczmetrics/APc(APfzmetrics/APf(zmetrics/mAP50-95(B)fitnessz faster-coco-eval unable to run: N)r    rQ   r   r   rP   rW   r   r   is_filerH   rI   r   faster_coco_evalr  r  loadResr   r)   r   im_filesr   r   r   paramsimgIdsevaluate
accumulate	summarizestats_as_dict	Exceptionr   )r(   r   r   r   r   r  ru   r  r  annor   r   iou_typerR   es                  r-   r   z DetectionValidator.coco_evaluate  sw   6 99DLLDLLc$**oKKB9+US\R]]`abG"I- >A99;=1#_(==;>+5i+EYK9	%/%<&&"#<=BI||I.#,Y#7 YKAx)dH^d^i^iC EIOOD[D[DdDd(eqT!W\\):(eCJJ%LLNNN$MMO ?B>O>OPX>YEN6!9Q<.:;ADARARSZA[E-fQil^1=>||@C@Q@QRW@XVAYq\N!<=@C@Q@QRW@XVAYq\N!<=@C@Q@QRW@XVAYq\N!<=!Y$ <<',-B'CE)$ u% )f   G!A!EFFGs9   $I <B:I 6%IBI "A+I I 	JI==J)NNNN)r   N)rR   N)N)r   Box)-__name__
__module____qualname____doc__r   r   rI   r   r<   r"   nnModulerZ   rc   Tensorr   rv   r   r   r   r   r   r   r   r   ndarrayr   r   utilsrE   Datasetr   
DataLoaderr   r   r   r   r   r   r   r   r   r	   r   __classcell__)r,   s   @r-   r   r      s~   0$&S#X 4S> "R%((// Rd R0l# lk k$tC<M7N2O k0l lT#s(^ lS#X l,D$sELL'8"9 D4S> DVZ[^`e`l`l[lVm D((Dc5<<.?)@$A ($sTWx. (]a (T.	)4S> 	)(]Dell):$; ]DcN ]W[\_acakak\kWl ] hc h hXc] h^c^i^i^n^n^v^v h`3 `C `EKKDTDTD_D_ `
d38n 
# 
$ 
" nr
#s(^
,0c5<<6G1H,I
OR
]efi]j
	
:.$sELL'8"9 .d .SXY\^aYaSb .jn .sw .&$sELL'8"9 S T .?tCH~ ?$sCx. ?. ,2(-=CH~= = 	=
 d3i(= c49n%= 
c3h=r.   r   )rK   pathlibr   typingr   r   r   r   r   r	   r   r   r"   ultralytics.datar
   r   r   ultralytics.engine.validatorr   ultralytics.utilsr   r   ultralytics.utils.checksr   ultralytics.utils.metricsr   r   r   ultralytics.utils.plottingr   r   ra   r.   r-   <module>r2     s?    
  : :   L L 6 ) 7 J J 2 r.   