a
    yf2;                     @   s   d dl Z d dl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mZ G d	d
 d
eZdS )    N)Path)build_dataloaderbuild_yolo_dataset	converter)BaseValidator)LOGGERops)check_requirements)ConfusionMatrix
DetMetricsbox_iou)output_to_targetplot_imagesc                       s   e Zd ZdZd* fdd	Zdd Zdd Zd	d
 Zdd Zdd Z	dd Z
dd Zdd Z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d(d) Z  ZS ),DetectionValidatoraR  
    A class extending the BaseValidator class for validation based on a detection model.

    Example:
        ```python
        from ultralytics.models.yolo.detect import DetectionValidator

        args = dict(model="yolov8n.pt", data="coco8.yaml")
        validator = DetectionValidator(args=args)
        validator()
        ```
    Nc                    s   t  ||||| d| _d| _d| _d| _d| _d| j_t	| j
| jd| _tddd| _| j | _g | _| jjrtd dS )	zAInitialize detection model with necessary variables and settings.NFdetect)save_diron_plotg      ?gffffff?
   u   WARNING ⚠️ 'save_hybrid=True' will append ground truth to predictions for autolabelling.
WARNING ⚠️ 'save_hybrid=True' will cause incorrect mAP.
)super__init__nt_per_classnt_per_imageis_cocois_lvis	class_mapargstaskr   r   r   metricstorchZlinspaceZiouvZnumelnioulbsave_hybridr   warning)self
dataloaderr   Zpbarr   
_callbacks	__class__ ^/var/www/html/django/DPS/env/lib/python3.9/site-packages/ultralytics/models/yolo/detect/val.pyr      s    zDetectionValidator.__init__c                    s    d j | jdd d< | jjr, d  n
 d  d  d< dD ]} |  | j |< qD| jjr d jdd \}}t d } d tj	||||f| jd	  fd
dt
|D | _ S )z/Preprocesses batch of images for YOLO training.imgT)Znon_blocking   )	batch_idxclsbboxes   Nr.   devicec                    s:   g | ]2}t j d   d |k  d |k gddqS )r-   r,   )dim)r   cat).0ibatchr.   r(   r)   
<listcomp>=   s   z1DetectionValidator.preprocess.<locals>.<listcomp>)tor1   r   Zhalffloatr!   shapelenr   tensorranger    )r#   r8   kheightwidthnbr(   r7   r)   
preprocess2   s    ( zDetectionValidator.preprocessc                 C   s
  | j | jjd}t|toFd|v oF|tj dpF|tj d| _	t|tobd|v ob| j	 | _
| j	rtt nttt|j| _| j j| j	s| j
o| j O  _|j| _t|j| _| j| j_| jj| j_t| j| jjd| _d| _g | _tg g g g g d| _d	S )
z'Initialize evaluation metrics for YOLO. Zcocozval2017.txtztest-dev2017.txtlvis)ncconfr   )tprH   pred_cls
target_cls
target_imgN)datagetr   split
isinstancestrendswithossepr   r   r   Zcoco80_to_coco91_classlistr?   r=   namesr   	save_jsontrainingrG   r   plotsplotr
   rH   confusion_matrixseenjdictdictstats)r#   modelvalr(   r(   r)   init_metricsD   s"    
"" 
zDetectionValidator.init_metricsc                 C   s   dd S )zBReturn a formatted string summarizing class metrics of YOLO model.z%22s%11s%11s%11s%11s%11s%11s)ClassZImagesZ	InstanceszBox(PRZmAP50z	mAP50-95)r(   )r#   r(   r(   r)   get_descX   s    zDetectionValidator.get_descc              	   C   s2   t j|| jj| jj| jd| jjp&| jj| jjdS )z4Apply Non-maximum suppression to prediction outputs.T)labelsZmulti_labelZagnosticmax_det)	r   Znon_max_suppressionr   rH   iour    
single_clsZagnostic_nmsrg   )r#   predsr(   r(   r)   postprocess\   s    zDetectionValidator.postprocessc           	      C   s   |d |k}|d |  d}|d | }|d | }|d jdd }|d	 | }t|rt|tj|| jd
g d  }tj||||d |||||dS ):Prepares a batch of images and annotations for validation.r,   r-   r2   r.   	ori_shaper*   r/   N	ratio_padr0   )   r   ro   r   rn   )r-   bboxrm   imgszrn   )	squeezer<   r=   r   Z	xywh2xyxyr   r>   r1   scale_boxes)	r#   sir8   idxr-   rq   rm   rr   rn   r(   r(   r)   _prepare_batchh   s    "z!DetectionValidator._prepare_batchc                 C   s:   |  }tj|d |ddddf |d |d d |S )rl   rr   N   rm   rn   rp   )cloner   rt   )r#   predpbatchprednr(   r(   r)   _prepare_predu   s
    $z DetectionValidator._prepare_predc              
   C   s  t |D ]\}}|  jd7  _t|}ttjd| jdtjd| 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| jjrd|d
d
df< | ||}|d
d
df |d< |d
d
df |d< |
rl| ||	||d< | jjrl| j||	| | j D ]}| j| ||  qv| jjr| ||d |  | jjr| || jj|d | jd t|d | j d  qd
S )zMetrics.ro   r   r0   )dtyper1   )rH   rJ   rI   r-   rq   rK   rL   N)
detections	gt_bboxesgt_cls   rx   rH   rJ   rI   im_filerm   rf   z.txt)	enumerater\   r=   r^   r   zerosr1   r   boolrw   popuniquer_   keysappendr   rY   r[   Zprocess_batchri   r}   _process_batchrW   pred_to_jsonsave_txtsave_one_txt	save_confr   r   stem)r#   rj   r8   ru   rz   Znprstatr{   r-   rq   nlr@   r|   r(   r(   r)   update_metrics}   sP    


 z!DetectionValidator.update_metricsc                 O   s   | j | j_ | j| j_dS )z8Set final values for metrics speed and confusion matrix.N)speedr   r[   )r#   r   kwargsr(   r(   r)   finalize_metrics   s    
z#DetectionValidator.finalize_metricsc                 C   s   dd | j  D }tj|d t| jd| _tj|d t| jd| _|	dd t
|r~|d  r~| jjf i | | jjS )z2Returns metrics statistics and results dictionary.c                 S   s&   i | ]\}}|t |d   qS )r   )r   r4   cpunumpy)r5   r@   vr(   r(   r)   
<dictcomp>       z0DetectionValidator.get_stats.<locals>.<dictcomp>rK   )Z	minlengthrL   NrI   )r_   itemsnpZbincountZastypeintrG   r   r   r   r=   anyr   processZresults_dict)r#   r_   r(   r(   r)   	get_stats   s    zDetectionValidator.get_statsc                 C   s   ddt | jj  }t|d| j| j g| j R   | j dkr`t	d| j
j d | j
jr| js| jdkrt | jrt| jjD ]<\}}t|| j| | j| | j| g| j|R   q| j
jrdD ]"}| jj| j| j || jd	 qd
S )z1Prints training/validation set metrics per class.z%22s%11i%11iz%11.3gallr   u"   WARNING ⚠️ no labels found in z, set, can not compute metrics without labelsro   )TF)r   rV   	normalizer   N)r=   r   r   r   infor\   r   sumZmean_resultsr"   r   r   verboserX   rG   r_   r   Zap_class_indexrV   r   Zclass_resultrY   r[   rZ   r   valuesr   )r#   pfr6   cr   r(   r(   r)   print_results   s    (",z DetectionValidator.print_resultsc                 C   s4   t ||ddddf }| |dddf ||S )a>  
        Return correct prediction matrix.

        Args:
            detections (torch.Tensor): Tensor of shape (N, 6) representing detections where each detection is
                (x1, y1, x2, y2, conf, class).
            gt_bboxes (torch.Tensor): Tensor of shape (M, 4) representing ground-truth bounding box coordinates. Each
                bounding box is of the format: (x1, y1, x2, y2).
            gt_cls (torch.Tensor): Tensor of shape (M,) representing target class indices.

        Returns:
            (torch.Tensor): Correct prediction matrix of shape (N, 10) for 10 IoU levels.

        Note:
            The function does not return any value directly usable for metrics calculation. Instead, it provides an
            intermediate representation used for evaluating predictions against ground truth.
        Nrx   r   )r   Zmatch_predictions)r#   r   r   r   rh   r(   r(   r)   r      s    z!DetectionValidator._process_batchra   c                 C   s   t | j||| j|| jdS )aG  
        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`. Defaults to None.
        )modestride)r   r   rM   r   )r#   Zimg_pathr   r8   r(   r(   r)   build_dataset   s    	z DetectionValidator.build_datasetc                 C   s&   | j ||dd}t||| jjdddS )z Construct and return dataloader.ra   )r8   r   Fr2   )shuffleZrank)r   r   r   workers)r#   Zdataset_pathZ
batch_sizedatasetr(   r(   r)   get_dataloader   s    z!DetectionValidator.get_dataloaderc              
   C   sH   t |d |d |d d|d |d | jd| d | j| jd	 d
S )zPlot validation image samples.r*   r,   r-   r2   r.   r   	val_batchz_labels.jpgpathsfnamerV   r   N)r   rs   r   rV   r   )r#   r8   nir(   r(   r)   plot_val_samples   s    z#DetectionValidator.plot_val_samplesc                 C   sF   t |d gt|| jjdR |d | jd| d | j| jd dS )zDPlots predicted bounding boxes on input images and saves the result.r*   )rg   r   r   z	_pred.jpgr   N)r   r   r   rg   r   rV   r   )r#   r8   rj   r   r(   r(   r)   plot_predictions  s    z#DetectionValidator.plot_predictionsc                 C   sT   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   )Resultsro   )r~   N   )pathrV   Zboxes)r   )Zultralytics.engine.resultsr   r   r   Zuint8rV   r   )r#   r|   r   r<   filer   r(   r(   r)   r     s    zDetectionValidator.save_one_txtc              	   C   s   t |j}| rt|n|}t|ddddf }|ddddf  |ddddf d 8  < t| | D ]N\}}| j	|| j
t|d  | jrdnd dd |D t|d dd	 qzdS )
z/Serialize YOLO predictions to COCO json format.Nrx   r/   r   ro   r   c                 S   s   g | ]}t |d qS )   )roundr5   xr(   r(   r)   r9   %  r   z3DetectionValidator.pred_to_json.<locals>.<listcomp>)image_idZcategory_idrq   Zscore)r   r   	isnumericr   r   Z	xyxy2xywhziptolistr]   r   r   r   r   )r#   r|   filenamer   r   boxpbr(   r(   r)   r     s    
0zDetectionValidator.pred_to_jsonc              
   C   s  | j jr| js| jrt| jr| jd }| jd d | jrDdnd| j j d }| jr`dnd}t	
d	| d
| d| d z>||fD ]}| sJ | dqt| jrdnd | jrddlm} ddlm} |t|}|t|}	|||	d}
n6ddlm}m} |t|}|t|}	|||	d}
dd | jjjD |
j_|
  |
  |
  | jrz|
  | jr|
j dd n|
j!d |
j!d g\|| j"j#d < || j"j#d < W n: t$y } z t	%| d|  W Y d}~n
d}~0 0 |S )zHEvaluates YOLO output in JSON format and returns performance statistics.zpredictions.jsonr   annotationszinstances_val2017.jsonZlvis_v1_z.jsonZpycocotoolsrF   z
Evaluating z mAP using z and z...z file not foundzpycocotools>=2.0.6zlvis>=0.5.3r   )COCO)COCOevalrq   )LVISLVISEvalc                 S   s   g | ]}t t|jqS r(   )r   r   r   r   r(   r(   r)   r9   F  r   z0DetectionValidator.eval_json.<locals>.<listcomp>Nr/   ZAP50ZAPr2   z unable to run: )&r   rW   r   r   r=   r]   r   rM   rO   r   r   is_filer	   Zpycocotools.cocor   Zpycocotools.cocoevalr   rQ   ZloadResrF   r   r   Z
_load_jsonr$   r   Zim_filesparamsZimgIdsevaluate
accumulateZ	summarizer   r_   resultsr   r   	Exceptionr"   )r#   r_   Z	pred_jsonZ	anno_jsonpkgr   r   r   annorz   ra   r   r   er(   r(   r)   	eval_json*  sF    $
("*zDetectionValidator.eval_json)NNNNN)ra   N)__name__
__module____qualname____doc__r   rD   rb   re   rk   rw   r}   r   r   r   r   r   r   r   r   r   r   r   r   __classcell__r(   r(   r&   r)   r      s(   1

r   )rS   pathlibr   r   r   r   Zultralytics.datar   r   r   Zultralytics.engine.validatorr   Zultralytics.utilsr   r   Zultralytics.utils.checksr	   Zultralytics.utils.metricsr
   r   r   Zultralytics.utils.plottingr   r   r   r(   r(   r(   r)   <module>   s   