@@ -345,6 +345,7 @@ def preprocess_true_boxes(true_boxes, true_labels, input_shape, anchors, num_cla
345
345
anchors_min = - anchors_max
346
346
valid_mask = box_sizes [:, 0 ] > 0
347
347
348
+
348
349
# Discard zero rows.
349
350
wh = box_sizes [valid_mask ]
350
351
# set the center of all boxes as the origin of their coordinates
@@ -355,7 +356,7 @@ def preprocess_true_boxes(true_boxes, true_labels, input_shape, anchors, num_cla
355
356
356
357
intersect_mins = np .maximum (boxes_min , anchors_min )
357
358
intersect_maxs = np .minimum (boxes_max , anchors_max )
358
- intersect_wh = np .maximum (intersect_maxs - intersect_mins , 0. )
359
+ intersect_wh = np .maximum (intersect_maxs - intersect_mins , 0. )
359
360
intersect_area = intersect_wh [..., 0 ] * intersect_wh [..., 1 ]
360
361
box_area = wh [..., 0 ] * wh [..., 1 ]
361
362
@@ -448,43 +449,80 @@ def parser_example(self, serialized_example):
448
449
449
450
return self .preprocess (image , true_labels , true_boxes )
450
451
452
+ def bbox_iou (A , B ):
453
+
454
+ intersect_mins = np .maximum (A [:, 0 :2 ], B [:, 0 :2 ])
455
+ intersect_maxs = np .minimum (A [:, 2 :4 ], B [:, 2 :4 ])
456
+ intersect_wh = np .maximum (intersect_maxs - intersect_mins , 0. )
457
+ intersect_area = intersect_wh [..., 0 ] * intersect_wh [..., 1 ]
458
+
459
+ A_area = np .prod (A [:, 2 :4 ] - A [:, 0 :2 ], axis = 1 )
460
+ B_area = np .prod (B [:, 2 :4 ] - B [:, 0 :2 ], axis = 1 )
461
+
462
+ iou = intersect_area / (A_area + B_area - intersect_area )
463
+
464
+ return iou
465
+
451
466
def evaluate (y_pred , y_true , num_classes , score_thresh = 0.5 , iou_thresh = 0.5 ):
452
467
453
468
num_images = y_true [0 ].shape [0 ]
454
- true_labels = {i :0 for i in range (num_classes )} # {class: count}
455
- pred_labels = {i :0 for i in range (num_classes )}
456
- true_positive = {i :0 for i in range (num_classes )}
469
+ true_labels_dict = {i :0 for i in range (num_classes )} # {class: count}
470
+ pred_labels_dict = {i :0 for i in range (num_classes )}
471
+ true_positive_dict = {i :0 for i in range (num_classes )}
457
472
458
473
for i in range (num_images ):
459
- true_labels_list = []
474
+ true_labels_list , true_boxes_list = [], []
460
475
for j in range (3 ): # three feature maps
461
- true_probs_temp = y_true [j ][i ][...,5 :]
462
- true_probs_temp = true_probs_temp [true_probs_temp .sum (axis = - 1 ) > 0 ]
463
- true_labels_list += list (np .argmax (true_probs_temp , axis = - 1 ))
476
+ true_probs_temp = y_true [j ][i ][...,5 : ]
477
+ true_boxes_temp = y_true [j ][i ][...,0 :4 ]
478
+
479
+ object_mask = true_probs_temp .sum (axis = - 1 ) > 0
480
+
481
+ true_probs_temp = true_probs_temp [object_mask ]
482
+ true_boxes_temp = true_boxes_temp [object_mask ]
483
+
484
+ true_labels_list += np .argmax (true_probs_temp , axis = - 1 ).tolist ()
485
+ true_boxes_list += true_boxes_temp .tolist ()
464
486
465
487
if len (true_labels_list ) != 0 :
466
- print (true_labels_list )
467
- for cls , count in Counter (true_labels_list ).items (): true_labels [cls ] += count
488
+ for cls , count in Counter (true_labels_list ).items (): true_labels_dict [cls ] += count
468
489
469
490
pred_boxes = y_pred [0 ][i :i + 1 ]
470
491
pred_confs = y_pred [1 ][i :i + 1 ]
471
492
pred_probs = y_pred [2 ][i :i + 1 ]
472
- pred_labels_list = cpu_nms (pred_boxes , pred_confs * pred_probs , num_classes ,
473
- 100 , score_thresh , iou_thresh )[2 ]
474
- pred_labels_list = [] if pred_labels_list is None else list (pred_labels_list )
475
-
476
- if len (pred_labels_list ) != 0 :
477
- for cls , count in Counter (pred_labels_list ).items (): pred_labels [cls ] += count
478
-
479
- for k in range (num_classes ):
480
- t = true_labels_list .count (k )
481
- p = pred_labels_list .count (k )
482
- true_positive [k ] += p if t >= p else t
483
-
484
- recall = sum (true_positive .values ()) / (sum (true_labels .values ()) + 1e-6 )
485
- precision = sum (true_positive .values ()) / (sum (pred_labels .values ()) + 1e-6 )
486
- avg_prec = [true_positive [i ] / (true_labels [i ] + 1e-6 ) for i in range (num_classes )]
487
- mAP = sum (avg_prec ) / num_classes
493
+
494
+ pred_boxes , pred_confs , pred_labels = cpu_nms (pred_boxes , pred_confs * pred_probs , num_classes ,
495
+ score_thresh = score_thresh , iou_thresh = iou_thresh )
496
+
497
+ true_boxes = np .array (true_boxes_list )
498
+ box_centers , box_sizes = true_boxes [:,0 :2 ], true_boxes [:,2 :4 ]
499
+
500
+ true_boxes [:,0 :2 ] = box_centers - box_sizes / 2.
501
+ true_boxes [:,2 :4 ] = true_boxes [:,0 :2 ] + box_sizes
502
+
503
+ pred_labels_list = [] if pred_labels is None else pred_labels .tolist ()
504
+ if pred_labels_list == []: continue
505
+
506
+ detected = []
507
+ for k in range (len (true_labels_list )):
508
+ # compute iou between predicted box and ground_truth boxes
509
+ iou = bbox_iou (true_boxes [k :k + 1 ], pred_boxes )
510
+ # Extract index of largest overlap
511
+ m = np .argmax (iou )
512
+ if iou [m ] >= iou_thresh and true_labels_list [k ] == pred_labels_list [m ] and m not in detected :
513
+ pred_labels_dict [true_labels_list [k ]] += 1
514
+ detected .append (m )
515
+ pred_labels_list = [pred_labels_list [m ] for m in detected ]
516
+
517
+ for c in range (num_classes ):
518
+ t = true_labels_list .count (c )
519
+ p = pred_labels_list .count (c )
520
+ true_positive_dict [c ] += p if t >= p else t
521
+
522
+ recall = sum (true_positive_dict .values ()) / (sum (true_labels_dict .values ()) + 1e-6 )
523
+ precision = sum (true_positive_dict .values ()) / (sum (pred_labels_dict .values ()) + 1e-6 )
524
+ avg_prec = [true_positive_dict [i ] / (true_labels_dict [i ] + 1e-6 ) for i in range (num_classes )]
525
+ mAP = sum (avg_prec ) / (sum ([avg_prec [i ] != 0 for i in range (num_classes )]) + 1e-6 )
488
526
489
527
return recall , precision , mAP
490
528
0 commit comments