
    kh8                     H    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	y)    N)compute_precision_recallcompute_average_precisioncompute_cor_loc)PerImageEvaluationc            	       P    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
y)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"              | _        | j'                          y)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/teggl/fontify/venv/lib/python3.12/site-packages/effdet/evaluation/object_detection_evaluation.py__init__z"ObjectDetectionEvaluation.__init__   s    @ APQQ2)#9/!5+- #5"4.'$8!.!$&!#% *,((4>>*O'%'XXdnnC%H"##%    c                    t               | _        t        | j                        D cg c]  }g  c}| _        t        | j                        D cg c]  }g  c}| _        t        j                  | j                        | _        t        j                  | j                  t              | _        | j                  j                  t        j                         t        j                  g| j                  z  | _        t        j                  g| j                  z  | _        t        j                  g| j                  z  | _        t        j"                  | j                  t              | _        yc c}w c c}w )z%Initializes internal data structures.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    !e-24>>-B C C383H&Iar&I#79xx7O4+-88DNN%+P(((--bff5%'VVHt~~$=!"$&&DNN!:VVHt~~5 "e D !D&Is   	E+	E0c                 $    | j                          y N)r$   )r%   s    r'   clear_detectionsz*ObjectDetectionEvaluation.clear_detectionsT   s    ##%r)   Nc                    || j                   v rt        j                  d|       y|| j                   |<   || j                  |<   || j                  |<   |*|j
                  d   }t        j                  |t              }|j                  t              }|| j                  |<   |*|j
                  d   }t        j                  |t              }|+|j
                  d   }t        j                  |t              }n.t        j                  |d      dk(  j                  t              }|j                  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(        s| j$                  |
xx   dz  cc<    y)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   r-   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   & %OO[]fg#+i *9Y'#+i ' q)I#%88IT#B 3:::F/C!!),& q)I"$((9D"A q)I&(hhy&E#')vvhV'D'I&Q&QX\&Q&]#188t8D.A  + ';=T&T# 0 	=K!vv!< <@S?S STXcc e'+';';bff 37R6R RSWbb?d (d$++K8<LOg<gg8vvo45**;71<7	=r)   c                    t        |      t        |      k7  st        |      t        |      k7  r+t        dt        |      z  t        |      t        |            || j                  v rt        j                  d|       y| j                  j                  |       || j                  v rX| j                  |   }| 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$                  j'                  ||||||	|
||		      \  }}}t)        | j*                        D ]Z  }||   j,                  d   dkD  s| j.                  |   j1                  ||          | j2                  |   j1                  ||          \ | xj4                  |z  c_        y)
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      )rC   r   r   )r   r
   r
   )	detected_boxesdetected_scoresdetected_class_labelsr   r   r   r   detected_masksr   )lenr   r,   rA   rB   addr   r   r   popr   r   r   r1   r    arrayr"   rD   r    compute_object_detection_metricsr-   r   rC   r.   appendr/   r0   )r%   rH   rR   rS   rT   rU   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   s   " ~#o"66#n:MQTUjQk:k!$^!4569/6J)*	, , +++OO^`ij	*%}}Y/H"229=O }}((3H#'#<#<Y#G "&":":9"Exxq!fE:H hhr5O%88)5A#%88Bd#; "$((2T":@@- /&;! /%9$7-! A 	# 	CB t~~& 	GAayq!A%%%a(//q	:++A.55l1oF	G 	448\\4r)   c           	      T   | j                   dk(  j                         rVt        j                  dt	        j
                  t	        j                  | j                   dk(              | j                  z          | j                  r6t	        j                  g t              }t	        j                  g t              }t        | j                        D ]  }| j                   |   dk(  r| j                  |   s7t	        j                  g t              }t	        j                  g t              }nDt	        j                  | j                  |         }t	        j                  | j                   |         }| j                  r,t	        j"                  |      }t	        j"                  |      }t%        ||| j                   |         \  }}t'        |      D 	cg c]%  \  }}	|	| j(                  k\  r|	| j*                  k  r|' }
}}	||
   }||
   }|| j,                  |<   || j.                  |<   |j1                         | j2                  |<   t5        ||      }|| j6                  |<   t        j8                  d|        t;        | j<                  | j>                        | _         | j                  rt	        j0                  | j                         }t%        |      \  }}t'        |      D 	cg c]%  \  }}	|	| j(                  k\  r|	| j*                  k  r|' }
}}	||
   }||
   }t5        ||      }nt	        jB                  | j6                        }t	        jB                  | j@                        }tE        | j6                  || j,                  | j.                  | j@                  |      S c c}	}w c c}	}w )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   zaverage_precision: %f)per_class_apmean_apper_class_precisionper_class_recallper_class_corlocsmean_corloc)#r!   rG   rA   rB   r   squeezeargwherer   r   rY   r    rD   r-   r   r.   concatenater/   r[   r   	enumerater   r   r5   r6   rF   r7   r   r2   debugr   r#   r0   r9   nanmeandict)r%   
all_scoresall_tp_fp_labelsrL   r\   r]   	precisionrecallindexvaluerecall_within_bound_indicesrecall_within_boundprecision_within_boundaverage_precisionrM   rc   rg   s                    r'   evaluatez"ObjectDetectionEvaluation.evaluate   sO    ++q0557OOI

2;;t'F'F!'KLMPTPdPddf $$"E2J!xx$7 0 	FK..{;q@((5"E2!xx%8(=(=k(JK!~~d.I.I+.VW((YYz6:
#%99-=|#L  8d&E&Ek&R!TIv +4F*;+&%000Ud>U>U5U +' + #))D"E%./J%K"5KD%%k22ED"";/-9-=-=-?Dk* 9:PRe f<MD,,[9MM13DE5	F8 !0&&(T(T!V $$!vvd&E&EF 8EUWg hIv*3F*;+&%000Ud>U>U5U +' + #))D"E%./J%K"/0FH[\Gjj!A!ABGjj!6!67997 $ 9 9!33"33	N 	N?+(+s   *N#*N$)NNNr<   )__name__
__module____qualname____doc__r   r(   r$   r=   rO   r`   ry    r)   r'   r   r   	   sU    E ),#&&+$'$'&+!"!$&88&tE&
 KO4=n ei>]@DNr)   r   )
rA   numpyr   effdet.evaluation.metricsr   r   r   &effdet.evaluation.per_image_evaluationr   r   r~   r)   r'   <module>r      s"      j j EHN HNr)   