
    Ng8                     P    d dl Z d dlZd dlmZmZmZ d dlmZ  G d d          Z	dS )    N)compute_precision_recallcompute_average_precisioncompute_cor_loc)PerImageEvaluationc            	       R    e Zd ZdZddddddddef	dZd	 Zd
 Z	 ddZ	 ddZ	d Z
dS )ObjectDetectionEvaluationz;Internal implementation of Pascal object detection metrics.g      ?g      ?i'  g        Fr   c                    |dk     rt          d           |
|||||	          | _        || _        || _        |	| _        || _        || _        || _        i | _        i | _	        i | _
        i | _        i | _        t          j        | j        t                    | _        t          j        | j        t"                    | _        |                                  dS )a  Constructor.
        Args:
            num_gt_classes: Number of ground-truth classes.
            matching_iou_threshold: IOU threshold used for matching detected boxes to ground-truth boxes.
            nms_iou_threshold: IOU threshold used for non-maximum suppression.
            nms_max_output_boxes: Maximum number of boxes returned by non-maximum suppression.
            recall_lower_bound: lower bound of recall operating area
            recall_upper_bound: upper bound of recall operating area
            use_weighted_mean_ap: (optional) boolean which determines if the mean
                average precision is computed directly from the scores and tp_fp_labels of all classes.
            label_id_offset: The label id offset.
            group_of_weight: Weight of group-of boxes.If set to 0, detections of the
                correct class within a group-of box are ignored. If weight is > 0, then
                if at least one detection falls within a group-of box with
                matching_iou_threshold, weight group_of_weight is added to true
                positives. Consequently, if no detection falls within a group-of box,
                weight group_of_weight is added to false negatives.
            per_image_eval_class: The class that contains functions for computing per image metrics.
        Raises:
            ValueError: if num_gt_classes is smaller than 1.
           z1Need at least 1 groundtruth class for evaluation.)num_gt_classesmatching_iou_thresholdnms_iou_thresholdnms_max_output_boxesgroup_of_weightdtypeN)
ValueErrorper_image_evalrecall_lower_boundrecall_upper_boundr   	num_classuse_weighted_mean_aplabel_id_offsetgt_boxesgt_class_labelsgt_masksgt_is_difficult_listgt_is_group_of_listnpzerosfloatnum_gt_instances_per_classintnum_gt_imgs_per_class_initialize_detections)selfr   r   r   r   r   r   r   r   r   per_image_eval_classs              i/var/www/html/ai-engine/env/lib/python3.11/site-packages/effdet/evaluation/object_detection_evaluation.py__init__z"ObjectDetectionEvaluation.__init__   s    @ APQQQ22)#9/!5+- - - #5"4.'$8!.!$&!#% *,(4>*O*O*O'%'XdnC%H%H%H"##%%%%%    c                 l   t                      | _        d t          | j                  D             | _        d t          | j                  D             | _        t          j        | j                  | _        t          j	        | j        t                    | _        | j                            t          j                   t          j        g| j        z  | _        t          j        g| j        z  | _        t          j        g| j        z  | _        t          j        | j        t                    | _        dS )z%Initializes internal data structures.c                     g | ]}g S  r,   .0_s     r'   
<listcomp>zDObjectDetectionEvaluation._initialize_detections.<locals>.<listcomp>I   s     C C C C C Cr)   c                     g | ]}g S r,   r,   r-   s     r'   r0   zDObjectDetectionEvaluation._initialize_detections.<locals>.<listcomp>J   s    &I&I&Iar&I&I&Ir)   r   N)setdetection_keysranger   scores_per_classtp_fp_labels_per_classr   r   'num_images_correctly_detected_per_classemptyr    average_precision_per_classfillnanprecisions_per_classrecalls_per_classsum_tp_classonescorloc_per_classr%   s    r'   r$   z0ObjectDetectionEvaluation._initialize_detectionsF   s    !ee C CU4>-B-B C C C&I&I53H3H&I&I&I#79x7O7O4+-8DN%+P+P+P((--bf555%'VHt~$=!"$&DN!:VHt~5 "e D D Dr)   c                 .    |                                   d S N)r$   rA   s    r'   clear_detectionsz*ObjectDetectionEvaluation.clear_detectionsT   s    ##%%%%%r)   Nc                    || j         v rt          j        d|           dS || j         |<   || j        |<   || j        |<   |(|j        d         }t          j        |t                    }|	                    t                    }|| j
        |<   |(|j        d         }t          j        |t                    }|)|j        d         }t          j        |t                    }n3t          j        |d          dk    	                    t                    }|	                    t                    }|| j        |<   ||z  }	t          | j                  D ]}
t          j        ||	 | z           |
k              }| j        t          j        |||	 z           |
k              z  }| j        |
xx         ||z   z  cc<   t          j        ||
k              r| j        |
xx         dz  cc<   dS )aw  Adds groundtruth for a single image to be used for evaluation.
        Args:
            image_key: A unique string/integer identifier for the image.
            gt_boxes: float32 numpy array of shape [num_boxes, 4] containing
                `num_boxes` groundtruth boxes of the format [ymin, xmin, ymax, xmax] in absolute image coordinates.
            gt_class_labels: integer numpy array of shape [num_boxes]
                containing 0-indexed groundtruth classes for the boxes.
            gt_is_difficult_list: A length M numpy boolean array denoting
                whether a ground truth box is a difficult instance or not. To support
                the case that no boxes are difficult, it is by default set as None.
            gt_is_group_of_list: A length M numpy boolean array denoting
                whether a ground truth box is a group-of box or not. To support the case
                that no boxes are groups-of, it is by default set as None.
            gt_masks: uint8 numpy array of shape [num_boxes, height, width]
                containing `num_boxes` groundtruth masks. The mask values range from 0 to 1.
        z=image %s has already been added to the ground truth database.Nr   r   )r
      )axisr
   )r   loggingwarningr   r   shaper   r   boolastyper   sumr   r4   r   r   r!   anyr#   )r%   	image_keyr   r   r   r   r   	num_boxesmask_presence_indicatormasked_gt_is_difficult_listclass_indexnum_gt_instancesnum_groupof_gt_instancess                r'   "add_single_ground_truth_image_infoz<ObjectDetectionEvaluation.add_single_ground_truth_image_infoW   s/   & %%O[]fgggF#+i *9Y'#+i ' q)I#%8IT#B#B#B 3:::FF/C!),& q)I"$(9D"A"A"A q)I&(hy&E&E&E##')vhV'D'D'D'I&Q&QX\&Q&]&]#188t8DD.A + ';=T&T# 00 	= 	=K!v!< <@S?S STXcc e  e'+';bf 37R6R RSWbb?d ?d (d$+K888<LOg<gg888vo455 =*;7771<777	= 	=r)   c                    t          |          t          |          k    s t          |          t          |          k    r;t          dt          |          z  t          |          t          |                    || j        v rt          j        d|           dS | j                            |           || j        v rO| j        |         }| j        |         }| j        	                    |          }| j
        |         }	| j        |         }
nt          j        ddgt                    }t          j        g t                     }|d}nt          j        g dt                    }t          j        g t"                    }	t          j        g t"                    }
| j                            ||||||	|
||		  	        \  }}}t)          | j                  D ]e}||         j        d         dk    rL| j        |                             ||                    | j        |                             ||                    f| xj        |z  c_        dS )
a  Adds detections for a single image to be used for evaluation.
        Args:
            image_key: A unique string/integer identifier for the image.
            detected_boxes: float32 numpy array of shape [num_boxes, 4] containing
                `num_boxes` detection boxes of the format [ymin, xmin, ymax, xmax] in
                absolute image coordinates.
            detected_scores: float32 numpy array of shape [num_boxes] containing
                detection scores for the boxes.
            detected_class_labels: integer numpy array of shape [num_boxes] containing
                0-indexed detection classes for the boxes.
            detected_masks: np.uint8 numpy array of shape [num_boxes, height, width]
                containing `num_boxes` detection masks with values ranging between 0 and 1.
        Raises:
            ValueError: if the number of boxes, scores and class labels differ in length.
        zgdetected_boxes, detected_scores and detected_class_labels should all have same lengths. Got[%d, %d, %d]z@image %s has already been added to the detection result databaseNr      )rJ   r   r   )r   r
   r
   )	detected_boxesdetected_scoresdetected_class_labelsr   r   r   r   detected_masksr   )lenr   r3   rH   rI   addr   r   r   popr   r   r   r8   r    arrayr"   rK   r    compute_object_detection_metricsr4   r   rJ   r5   appendr6   r7   )r%   rO   rY   rZ   r[   r\   r   r   r   r   r   scorestp_fp_labels$is_class_correctly_detected_in_imageis                  r'   add_single_detected_image_infoz8ObjectDetectionEvaluation.add_single_detected_image_info   sc   " ~#o"6"666#n:M:MQTUjQkQk:k:k!$^!4!4569/6J6J)**	, , , +++O^`ijjjF	***%%}Y/H"29=O }((33H#'#<Y#G "&":9"Exq!fE:::H hr555O%8)))5AAA#%8Bd#;#;#; "$(2T":":":@@- /&;! /%9$7-! A 	# 	# 	CB t~&& 	G 	GAayq!A%%%a(//q	:::+A.55l1oFFF448\\4444r)   c           	      .     j         dk                                    rJt          j        dt	          j        t	          j         j         dk                         j        z               j        r6t	          j	        g t                    }t	          j	        g t                    }t           j                  D ]q} j         |         dk    r j        |         s7t	          j	        g t                    }t	          j	        g t                    }n>t	          j         j        |                   }t	          j         j        |                   } j        r*t	          j        ||          }t	          j        ||          }t%          || j         |                   \  }} fdt'          |          D             }||         }	||         }
|
 j        |<   |	 j        |<   |                                 j        |<   t1          |
|	          }| j        |<   t          j        d|           st7           j         j                   _         j        rit	          j         j                   }t%          |||          \  }} fdt'          |          D             }||         }	||         }
t1          |
|	          }nt	          j         j                  }t	          j         j                  }tA           j        | j         j         j        |          S )a#  Compute evaluation result.
        Returns:
            A dict with the following fields -
                average_precision: float numpy array of average precision for each class.
                mean_ap: mean average precision of all classes, float scalar
                precisions: List of precisions, each precision is a float numpy array
                recalls: List of recalls, each recall is a float numpy array
                corloc: numpy float array
                mean_corloc: Mean CorLoc score for each class, float scalar
        r   z7The following classes have no ground truth examples: %sr   c                 F    g | ]\  }}|j         k    |j        k    |S r,   r   r   r.   indexvaluer%   s      r'   r0   z6ObjectDetectionEvaluation.evaluate.<locals>.<listcomp>   B     + + +&%000Ud>U5U5U 5U5U5Ur)   zaverage_precision: %fc                 F    g | ]\  }}|j         k    |j        k    |S r,   rj   rk   s      r'   r0   z6ObjectDetectionEvaluation.evaluate.<locals>.<listcomp>  rn   r)   )per_class_apmean_apper_class_precisionper_class_recallper_class_corlocsmean_corloc)!r!   rN   rH   rI   r   squeezeargwherer   r   r`   r    rK   r4   r   r5   concatenater6   rb   r   	enumerater<   r=   rM   r>   r   r9   debugr   r#   r7   r@   nanmeandict)r%   
all_scoresall_tp_fp_labelsrS   rc   rd   	precisionrecallrecall_within_bound_indicesrecall_within_boundprecision_within_boundaverage_precisionrT   rq   ru   s   `              r'   evaluatez"ObjectDetectionEvaluation.evaluate   sN    +q05577 	fOI
2;t'F!'KLLMMPTPddf f f $ 	8"E222J!x$777 00 	F 	FK.{;q@@(5 X"E222!x%888(=k(JKK!~d.I+.VWW( MYz6::
#%9-=|#L#L  8d&Ek&R!T !TIv+ + + +*3F*;*;+ + +' #))D"E%./J%K"5KD%k22ED";/-9-=-=-?-?Dk* 9:PRe f f<MD,[9M13DEEEE /&(T!V !V $ 	C!vd&EFF 8EUWg h hIv+ + + +*3F*;*;+ + +' #))D"E%./J%K"/0FH[\\GGj!ABBGj!67797 $ 9!3"3	N N N 	Nr)   )NNNrC   )__name__
__module____qualname____doc__r   r(   r$   rD   rV   rg   r   r,   r)   r'   r   r   	   s        EE ),#&&+$'$'&+!"!$&88& 8& 8& 8&tE E E& & &
 KO4= 4= 4= 4=n ei>] >] >] >]@DN DN DN DN DNr)   r   )
rH   numpyr   effdet.evaluation.metricsr   r   r   &effdet.evaluation.per_image_evaluationr   r   r,   r)   r'   <module>r      s         j j j j j j j j j j E E E E E EHN HN HN HN HN HN HN HN HN HNr)   