赞
踩
博主在这一个问题上犯了两个错,本文提供的方法不仅仅适用于SSD的eval.py
同样适用于解决其他项目中的voc_eval.py。
博主思考查询了一晚上,若对你有帮助,给个赞!!!
def voc_eval(detpath, annopath, imagesetfile, classname, cachedir, ovthresh=0.5, use_07_metric=False): if not os.path.isdir(cachedir): os.mkdir(cachedir) cachefile = os.path.join(cachedir, 'annots.pkl') # read list of images with open(imagesetfile, 'r') as f: lines = f.readlines() imagenames = [x.strip() for x in lines] # print(imagenames) if not os.path.isfile(cachefile): # load annots recs = {} for i, imagename in enumerate(imagenames): recs[imagename] = parse_rec(annopath % (imagename)) if i % 100 == 0: print('Reading annotation for {:d}/{:d}'.format( i + 1, len(imagenames))) # save print('Saving cached annotations to {:s}'.format(cachefile)) with open(cachefile, 'wb') as f: pickle.dump(recs, f) else: # load with open(cachefile, 'rb') as f: recs = pickle.load(f) # extract gt objects for this class class_recs = {} npos = 0 for imagename in imagenames: # print(imagename) # for obj in recs[imagename]: # if obj['name'] == classname: # print('obj[name]:', obj['name'], classname) R = [obj for obj in recs[imagename] if obj['name'] == classname] # print('R', len(R)) # for obj in recs[imagename]: # print('classname:', classname, 'obj[name]:', obj['name']) bbox = np.array([x['bbox'] for x in R]) # difficult = np.array([x['difficult'] for x in R]).astype(np.bool) difficult = np.zeros(len(R)).astype(np.bool) det = [False] * len(R) # npos = npos + sum(~difficult) # 没有difficult 则nops就为gt npos = npos + len(R) # len(R) gt ground truth的数量 class_recs[imagename] = {'bbox': bbox, 'difficult': difficult, 'det': det} print('npos', npos) # read dets detfile = detpath.format(classname) # print(detfile) with open(detfile, 'r') as f: lines = f.readlines() if any(lines) == 1: splitlines = [x.strip().split(' ') for x in lines] image_ids = [x[0] for x in splitlines] confidence = np.array([float(x[1]) for x in splitlines]) BB = np.array([[float(z) for z in x[2:]] for x in splitlines]) # sort by confidence sorted_ind = np.argsort(-confidence) sorted_scores = np.sort(-confidence) BB = BB[sorted_ind, :] image_ids = [image_ids[x] for x in sorted_ind] # go down dets and mark TPs and FPs nd = len(image_ids) tp = np.zeros(nd) fp = np.zeros(nd) for d in range(nd): R = class_recs[image_ids[d]] bb = BB[d, :].astype(float) ovmax = -np.inf BBGT = R['bbox'].astype(float) if BBGT.size > 0: # compute overlaps # intersection ixmin = np.maximum(BBGT[:, 0], bb[0]) iymin = np.maximum(BBGT[:, 1], bb[1]) ixmax = np.minimum(BBGT[:, 2], bb[2]) iymax = np.minimum(BBGT[:, 3], bb[3]) iw = np.maximum(ixmax - ixmin, 0.) ih = np.maximum(iymax - iymin, 0.) inters = iw * ih uni = ((bb[2] - bb[0]) * (bb[3] - bb[1]) + (BBGT[:, 2] - BBGT[:, 0]) * (BBGT[:, 3] - BBGT[:, 1]) - inters) overlaps = inters / uni ovmax = np.max(overlaps) jmax = np.argmax(overlaps) if ovmax > ovthresh: if not R['difficult'][jmax]: if not R['det'][jmax]: tp[d] = 1. R['det'][jmax] = 1 else: fp[d] = 1. # fp[d] = 1. else: fp[d] = 1. # compute precision recall fp = np.cumsum(fp) tp = np.cumsum(tp) rec = tp / float(npos) print(fp, tp, rec) # avoid divide by zero in case the first detection matches a difficult # ground truth prec = tp / np.maximum(tp + fp, np.finfo(np.float64).eps) ap = voc_ap(rec, prec, use_07_metric) else: rec = -1. prec = -1. ap = -1. return rec, prec, ap
if not R['difficult'][jmax]:
if not R['det'][jmax]:
tp[d] = 1.
R['det'][jmax] = 1
else:
fp[d] = 1.`
报错,因此需要做出如下更改,因为无difficult,意味着difficult全为0,difficult = np.zeros(len®).astype(np.bool)用其替换就可以了,然后将原来的npos=npos+sum(~difficult)这句可以修改也可以不改,改的话可以直接用len®代替sum部分,因为len®就是gt目标数量。如此基本上就不会出现MAP为0的情况了。
yolo可视化——loss、Avg IOU、P-R、mAP、Recall (没有xml文件的情况)
Faster R-CNN/R-FCN里mAP的计算过程(voc_eval.py解析)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。