cocoeval 解析

1、Params类:

对于COCO格式的数据检测,我们主要分为不同的IoU阈值,不同的面积范围,单张图片的最大检测数量。在这些不同的参数下,会得到不同的AP与AR。
所以在这个类中,我们需要指定这些参数的数值范围,具体可看下面贴出的代码。

  • 标准的即IoU阈值设置为从0.5-0.95 间隔0.05,一共10个阈值
  • AR的阈值为0-1 间隔0.01 ,一共101个阈值
  • 面积范围为 small(0~32) medium(32~96) large(96~10**5) 一共 3个
  • 检测最大数,按照置信度分数排序后选择最大检测数范围内的det结果。

2、COCOeval类:

COCOeval类是COCO api中最复杂的类了,主要包括以下函数

cocoeval 解析_第1张图片

 2.1 __init__(self, cocoGT=None, cocoDt=None, iouType='segm')

创建COCOeval这个类的时候,我们需要传入两个COCO 类别的instance,一个是gt对应的COCO,一个是det对应的COCO,用来初始化det的anno和gt的anno,关于COCO的类别,那么关于COCO类,可以参考:

MSCOCO api详解 —— Keypoints - 知乎

COCO API-COCO模块在det中的应用_张学渣的博客-CSDN博客

__init__ 函数中需要注意:

self.params = Params(iouType=iouType) # parameters

它用了一个外部类,将评估过程中重要的参数隐式的初始化在COCOeval内你敢信?并且这个self.params在后面的操作里,有多次的反复赋值、修改的操作。因此我们在使用不同格式的keypoints时,这里是也是唯一我们需要重载COCOeval的成员方法。

2.2 _prepare(self):

设置GT中的ignore flag,初始化空evaluation结果之类的一些常规操作。

会生成gt与dt的字典列表,用[img_id,cat_id]作为key,value即为这个指定图片指定类别对应的所有ann信息,是一个list形式。根据这两个字典列表

2.3 computeIoU(self, imgId, catId):

根据image_id和cat_id计算这张图片里所有GT、DT的iou矩阵,主要用于bbox和segmentation;

2.4 computeOks(self, imgId, catId):

根据image_id和cat_id计算这张图片里所有GT、DT的Oks矩阵,也就是Sec 1.2.里OKS的计算源码出处。这里OKS矩阵的维度是 

2.5 evaluateImg(self, imgId, catId, aRng, maxDet): 

根据image_id和cat_id,以及evaluate函数计算得到的iou矩阵,计算在给定的area rang和maxDet下不同iouThreshold下成功的匹配/不成功的匹配矩阵。

说起来很拗口,简单来说,这个方法传入固定的img_id,cat_id,aRng,maxDet,我们可以得到对应的img在特定类别,特定面积阈值,特定最大检测数下的检测结果。

  • 对于面积阈值来说,如果ann对应的bbox超过了aRng的范围就设置为ignore
  • 对于最大检测数,按照置信度排序后取出前最大检测数个即可

把这个检测结果按照K,A,M的顺序堆叠,可以得到self.evalImgs这个list,这个list包含了所有图片在所有IoU阈值,面积阈值,最大检测数下的所有检测结果。

返回的重要数据包括:

  • 预测框所匹配的真实框id、真实框所匹配的预测框id
  • 判定真实框和预测框是否满足条件的数组
  • 预测框的分数

然后我们就要开始介绍COCOeval的评估三板斧了

2.6 evaluate(self):

这里evaluate主要做了以下几件事:

  1. 一些边界检查,调用_prepare方法, 生成gt与dt的字典列表,根据这两个字典列表,我们可以生成iou计算,iou计算也以[img_id,cat_id]作为key,value是一个M*N维的ndarry矩阵,m为dt的个数,n为gt的个数。
  2. 根据我们初始化COCOeval类时提供的iouType判断是keypoints还是bbox/segmentation评估,选择不同的上面提到的IOU计算函数;
  3. 对每一张图片、每一个类别,分别计算它的iou矩阵;
  4. 计算iou矩阵后,利用上面的evaluateImg来计算每一张图片、每一个类别在不同条件下的检测结果;

这里有一个需要理解好的概念,就是det ignore,可以理解为可以忽略的检测,只有一个检测不是需要忽略的检测的时候,它才会被计入precision和recall。那么什么样的det是可以被ignore的呢:

  • 超出area range并且没有对应的ground truth;
  • 和一个可以被ignore的ground truth匹配了;

2.6 accumulate(self, p = None):

先看懂这篇文章,否者这个函数很难理解:cocoapi如何计算map_「已注销」的博客-CSDN博客_coco map计算

上面我们通过evaluate得到了每一个图片、每一个类别在 iouThreshold、area range、maxDet下的结果,那么在这一步我们需要将它们在整个数据集上汇总结果了。
最终返回的是所有图片在不同IoU阈值、不同AR、不同类别、不同面积阈值、不同最大检测数下的Ap与AR,以numpy数组的返回,即precision(T,R,K,A,M) recall(T,K,A,M)。

作者在这里把我们前面提到的参数Params作为一个函数的输入,似乎本意是希望能够更方便的在更多维度上统计结果,但是偏偏前面的evaluate又是在默认的参数上进行的,确实有一种还未完全实现功能。

2.7 summarize(self):

针对上述accumulate获得的precision、recall矩阵,在不同的维度上进行统计,然后再呈现结果。
函数内部会根据传入的具体的IoU阈值,面积阈值,最大检测数的值返回上述precision和recall中对应维的检测结果,我们就也可以自定义形式返回我们想要的各种参数下的AP与AR啦。
这里没有什么特别的需要注意的。我们常看到的mAP也就是出自于此。

1、COCO API-深入解析cocoeval在det中的应用_张学渣的博客-CSDN博客

2、MSCOCO api详解 —— Keypoints - 知乎

你可能感兴趣的:(Deep,Learning,人工智能)