P_true N_true
P_pred TP Fp
N_pred FN TN
P N
- TP(真正样本,与真实框IoU大于阈值的框) FP(假正样本,与真实框IoU小于阈值的框) TN(真负样本,背景) FN(假负样本,没有检测出的正样本)
- IoU:(A and B)/(A or B) A与B的交集除以A与B的并集
- precision:准确率,查全率。TP/(TP+FP)= TP/num_pred,数值越大,说明FP数量越少,准确率越高,但是没有考虑FN(可能有漏检)。
- recall:召回率,查准率。TP/(TP+FN)= TP/num_sample,数值越大,说明被检测到的正样本越多,效果越好,但是没有考虑FP(如果把背景也判断成前景,则效果不好)。
- F score:几何平均分,(BB+1)PR/(BBP+R),B用来调节PR的权重,当B=1,F1 score。 是precision和recall的加权,考虑两个评价指标的优劣。precision和recall是此消彼长的关系。
- Average Precision:单类平均准确率。是PR曲线的面积。
样本 置信度 正负样本 累计tp 累计fp precision recall
1 0.97 True 1 0 1.0 0.1
2 0.87 True 2 0 1.0 0.2
3 0.84 True 3 0 1.0 0.3
4 0.8 True 4 0 1.0 0.4
5 0.69 False 4 1 0.8 0.4
6 0.58 True 5 1 0.83 0.5
7 0.43 False 5 2 0.71 0.5
8 0.19 True 6 2 0.75 0.6
9 0.02 False 6 3 0.67 0.6
10 0.03 False 6 4 0.6 0.6
import numpy as np
img_ids = None
class_recs = None
BB = None
nd = len(img_ids)
thred = 0.5
npos = 100
tp = np.zeros(nd)
fp = np.zeros(nd)
for d in range(nd):
R = class_recs[img_ids[d]]
bb = BB[d,:].astype(float)
idx = -np.inf
BBGT = R['bbox'].astype(float)
if BBGT.size>0:
x1y1 = np.maximum(BBGT[:,:2],bb[:2])
x2y2 = np.maximum(BBGT[:, 2:], bb[2:])
wh = np.maximum(x2y2-x1y1+1,0)
inters = wh[0]*wh[1]
bb_areas = (bb[2]-bb[0]+1.0)*(bb[3]-bb[1]+1.0)
BBGT_ares = (BBGT[:,2]-BBGT[:,0]+1.0)*(BBGT[:,3]-BBGT[:,1]+1.0)
ious = inters/(bb_areas+BBGT_ares-inters)
iou = np.max(ious)
idx = np.argmax(ious)
if idx>thred:
if not R['difficult'][idx]:
if not R['det'][idx]:
tp[d]=1.
R['det'][idx]=1
else:
fp[d] = 1.
else:
fp[d] = 1.
fp = np.cumum(fp)
tp = np.cumum(tp)
rec = tp/float(npos)
prec = tp/np.maximum(tp+fp,np.finfo(np.float64).eps)
def voc_ap(rec,prec):
mrec = np.concatenate(([0.],rec,[1.]))
mpre = np.concatenate(([0.],prec,[0.]))
for i in range(mpre.size-1,0,-1):
mpre[i-1]=np.maximum(mpre[i-1],mpre[i])
i = np.where(mpre[1:] != mpre[:-1])[0]
ap = np.sum((mrec[i+1]-mrec[i])*mrec[i+1])
return ap