| import os
|
| import xml.etree.ElementTree as ET
|
|
|
| from PIL import Image
|
| from tqdm import tqdm
|
|
|
| from utils.utils import get_classes
|
| from utils.utils_map import get_coco_map, get_map
|
| from ssd import SSD
|
|
|
| if __name__ == "__main__":
|
| '''
|
| Recall和Precision不像AP是一个面积的概念,因此在门限值(Confidence)不同时,网络的Recall和Precision值是不同的。
|
| 默认情况下,本代码计算的Recall和Precision代表的是当门限值(Confidence)为0.5时,所对应的Recall和Precision值。
|
|
|
| 受到mAP计算原理的限制,网络在计算mAP时需要获得近乎所有的预测框,这样才可以计算不同门限条件下的Recall和Precision值
|
| 因此,本代码获得的map_out/detection-results/里面的txt的框的数量一般会比直接predict多一些,目的是列出所有可能的预测框,
|
| '''
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| map_mode = 0
|
|
|
|
|
|
|
|
|
| classes_path = 'model_data/voc_classes.txt'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| MINOVERLAP = 0.5
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| confidence = 0.02
|
|
|
|
|
|
|
|
|
|
|
| nms_iou = 0.5
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| score_threhold = 0.5
|
|
|
|
|
|
|
| map_vis = False
|
|
|
|
|
|
|
|
|
| VOCdevkit_path = 'VOCdevkit'
|
|
|
|
|
|
|
| map_out_path = 'map_out'
|
|
|
| image_ids = open(os.path.join(VOCdevkit_path, "VOC2007/ImageSets/Main/test.txt")).read().strip().split()
|
|
|
| if not os.path.exists(map_out_path):
|
| os.makedirs(map_out_path)
|
| if not os.path.exists(os.path.join(map_out_path, 'ground-truth')):
|
| os.makedirs(os.path.join(map_out_path, 'ground-truth'))
|
| if not os.path.exists(os.path.join(map_out_path, 'detection-results')):
|
| os.makedirs(os.path.join(map_out_path, 'detection-results'))
|
| if not os.path.exists(os.path.join(map_out_path, 'images-optional')):
|
| os.makedirs(os.path.join(map_out_path, 'images-optional'))
|
|
|
| class_names, _ = get_classes(classes_path)
|
|
|
| if map_mode == 0 or map_mode == 1:
|
| print("Load model.")
|
| ssd = SSD(confidence = confidence, nms_iou = nms_iou)
|
| print("Load model done.")
|
|
|
| print("Get predict result.")
|
| for image_id in tqdm(image_ids):
|
| image_path = os.path.join(VOCdevkit_path, "VOC2007/JPEGImages/"+image_id+".jpg")
|
| image = Image.open(image_path)
|
| if map_vis:
|
| image.save(os.path.join(map_out_path, "images-optional/" + image_id + ".jpg"))
|
| ssd.get_map_txt(image_id, image, class_names, map_out_path)
|
| print("Get predict result done.")
|
|
|
| if map_mode == 0 or map_mode == 2:
|
| print("Get ground truth result.")
|
| for image_id in tqdm(image_ids):
|
| with open(os.path.join(map_out_path, "ground-truth/"+image_id+".txt"), "w") as new_f:
|
| root = ET.parse(os.path.join(VOCdevkit_path, "VOC2007/Annotations/"+image_id+".xml")).getroot()
|
| for obj in root.findall('object'):
|
| difficult_flag = False
|
| if obj.find('difficult')!=None:
|
| difficult = obj.find('difficult').text
|
| if int(difficult)==1:
|
| difficult_flag = True
|
| obj_name = obj.find('name').text
|
| if obj_name not in class_names:
|
| continue
|
| bndbox = obj.find('bndbox')
|
| left = bndbox.find('xmin').text
|
| top = bndbox.find('ymin').text
|
| right = bndbox.find('xmax').text
|
| bottom = bndbox.find('ymax').text
|
|
|
| if difficult_flag:
|
| new_f.write("%s %s %s %s %s difficult\n" % (obj_name, left, top, right, bottom))
|
| else:
|
| new_f.write("%s %s %s %s %s\n" % (obj_name, left, top, right, bottom))
|
| print("Get ground truth result done.")
|
|
|
| if map_mode == 0 or map_mode == 3:
|
| print("Get map.")
|
| get_map(MINOVERLAP, True, score_threhold = score_threhold, path = map_out_path)
|
| print("Get map done.")
|
|
|
| if map_mode == 4:
|
| print("Get map.")
|
| get_coco_map(class_names = class_names, path = map_out_path)
|
| print("Get map done.")
|
|
|