参数解释
先对以下4个主要输入参数进行解释
tp:一个shape为(n, 10)的的数组,其中n是测试集检测出的所有物体总和,10表示的是该物体在(0.5,0.05,0.95)这 10个IOU阈值上的匹配结果,值为true或false,true表示在该iou阈值下,这个检测框检测到了物体且类别正确,可以作为true positive样本
conf:上述每个检测框的类别置信度
pred_cls:上述每个检测框的类别标签
target_cls:该测试集实际包含的物体类别列表,该参数提供两个信息:1、测试集包含哪些类别(用来按类统计map);2、一共有多少标注物体(用来计算recall)
关键输出项
该函数计算了三个核心输出项
recall:每类计算一个recall,每类recall的形状(nc,10),nc为上文检测框体中该类物体的个数,10还是对应10个iou阈值
precision:同recall
py:所有类的precision数值,形状为(cn,1000),cn表示类别个数,比如只检测人和车两个类,那么cn为2,1000表示每类有1000个precision,分别对应(0.001,0.001,1)这1000个recall
计算原理
1、将conf降序排列,同时将pred_cls和tp也按对应次序重排
i = np.argsort(-conf)
tp, conf, pred_cls = tp[i], conf[i], pred_cls[i]
2、将tp累加,然后计算recall和precision,因为tp是按conf降序排列的,所以recall和precision也是按conf降序排列的,所以precison和recall可以看作conf的函数,当我们要计算比如conf阈值为0.2时的p和r时,只需要进行插值即可
这里先将conf阈值用很低的值(比如0.0001)计算出大量的box,然后对这些box进行conf降序排列,并对每个conf计算大于该conf的所有box的p和r
px, py = np.linspace(0, 1, 1000), []
fpc = (1 - tp[i]).cumsum(0)
tpc = tp[i].cumsum(0)
recall = tpc / (n_gt + 1e-16)
precision = tpc / (tpc + fpc)
py.append(np.interp(px, recall[:, 0], precision[:, 0]))