MS COCO 目标检测 、人体关键点检测评价指标

在这里插入图片描述



1 MS COCO 目标检测评价指标

COCO 目标检测评价指标(官网)

在这里插入图片描述

The evaluation metrics for detection with bounding boxes and segmentation masks are identical in all respects except for the IoU computation (which is performed over boxes or masks, respectively).
在这里插入图片描述

目标检测和分割评价指标仅是 IoU 的计算方式不同

Thesholding the IoU defines matches between the ground truth and predicted objects and allows computing precision-recall curves.

在这里插入图片描述

在这里插入图片描述

  • C75 就是 AP0.75
  • C50 就是 AP0.5
  • Loc 就是用 GT 的 bbox,也即 IoU 为 1(框出来的,与 GT 有交集用 GT 替换)
  • Sim 同超类的近亲混淆(被纠正),比如把老虎识别成了猫
  • Oth 类别混淆(被纠正),比如把狗识别成了猫
  • BG 与背景混淆(被纠正),把背景识别成了猫(多框了)
  • FN,其他类别的错误(被纠正),漏框了,有猫没有框出来

2 MS COCO 人体关键点检测评价指标

2017 MS COCO 数据集

over 200,000 images and 250,000 person instance,17 keypoints

  • train 2017:57K images and 150K person instance
  • val 2017:5000 images
  • test-dev 2017:20K images

17 个关键点,多人

"keypoints": [
    "nose",
    "left_eye",
    "right_eye",
    "left_ear",
    "right_ear",
    "left_shoulder",
    "right_shoulder",
    "left_elbow",
    "right_elbow",
    "left_wrist",
    "right_wrist",
    "left_hip",
    "right_hip",
    "left_knee",
    "right_knee",
    "left_ankle",
    "right_ankle"
]

在这里插入图片描述
图片来自 COCO Dataset person_keypoints.json 解析

在 COCO annotation 中,关键点的描述是一个长度为 51 维的列表,每三个表示一个关键点 ( x , y , v ) (x,y,v) (x,y,v) v v v 是 flag

更详细的总结与可视化可以参考 MSCOCO数据标注详解


COCO 人体关键点检测评价指标(官网)

定义了 object keypoint similarity (OKS) which plays the same role as the IoU.

在这里插入图片描述

  • d,预测的关键点和 GT 之间的欧几里得距离

  • s,scale 的控制,表示这个人所占的面积大小平方根, 根据 groundtruth 里人的 box 计算得到,注意,比例是固定的,eg 192:256,大小为实际 bbox 的 1.25 倍
    在这里插入图片描述

  • k,表示骨骼点的归一化因子,这个因子是通过对已有的数据集中所有 groundtruth 计算的标准差而得到的,反映出当前骨骼点对与整体的影响程度。值越大,说明在整个数据集中对这个点的标注效果越差; 值越小,说明整个数据集中对这个点的标注效果越好!一般取 2 σ \sigma σ,其中
    在这里插入图片描述
    在这里插入图片描述

  • v,visibility flag
    v = 0,GT 没有点
    v = 1,GT 有点但是看不见(被遮挡)
    v = 2, GT 有点也看得见


代码可以参考下这个(做 NMS 时,计算得分最高框框的 key-points 和其他框框中 key-point 的 oks):

https://github.com/leoxiaobin/deep-high-resolution-net.pytorch/blob/master/lib/nms/nms.py

def oks_iou(g, d, a_g, a_d, sigmas=None, in_vis_thre=None):
    if not isinstance(sigmas, np.ndarray):
        sigmas = np.array([.26, .25, .25, .35, .35, .79, .79, .72, .72, .62, .62, 1.07, 1.07, .87, .87, .89, .89]) / 10.0
    vars = (sigmas * 2) ** 2
    xg = g[0::3]
    yg = g[1::3]
    vg = g[2::3]
    ious = np.zeros((d.shape[0]))
    for n_d in range(0, d.shape[0]):
        xd = d[n_d, 0::3]
        yd = d[n_d, 1::3]
        vd = d[n_d, 2::3]
        dx = xd - xg
        dy = yd - yg
        e = (dx ** 2 + dy ** 2) / vars / ((a_g + a_d[n_d]) / 2 + np.spacing(1)) / 2
        if in_vis_thre is not None:
            ind = list(vg > in_vis_thre) and list(vd > in_vis_thre)
            e = e[ind]
        ious[n_d] = np.sum(np.exp(-e)) / e.shape[0] if e.shape[0] != 0 else 0.0
    return ious

注意上述代码面积的计算,是两个面积加起来除以2,没有平方,np.spacing(1) 超级小的数,防止分母为 0


再看看 coco API 中计算 OKS 的代码,来自

https://github.com/cocodataset/cocoapi/blob/master/PythonAPI/pycocotools/cocoeval.py

    def computeOks(self, imgId, catId):
        p = self.params
        # dimention here should be Nxm
        gts = self._gts[imgId, catId]
        dts = self._dts[imgId, catId]
        inds = np.argsort([-d['score'] for d in dts], kind='mergesort')
        dts = [dts[i] for i in inds]
        if len(dts) > p.maxDets[-1]:
            dts = dts[0:p.maxDets[-1]]
        # if len(gts) == 0 and len(dts) == 0:
        if len(gts) == 0 or len(dts) == 0:
            return []
        ious = np.zeros((len(dts), len(gts)))
        sigmas = p.kpt_oks_sigmas
        vars = (sigmas * 2)**2
        k = len(sigmas)
        # compute oks between each detection and ground truth object
        for j, gt in enumerate(gts):
            # create bounds for ignore regions(double the gt bbox)
            g = np.array(gt['keypoints'])
            xg = g[0::3]; yg = g[1::3]; vg = g[2::3]
            k1 = np.count_nonzero(vg > 0)
            bb = gt['bbox']
            x0 = bb[0] - bb[2]; x1 = bb[0] + bb[2] * 2
            y0 = bb[1] - bb[3]; y1 = bb[1] + bb[3] * 2
            for i, dt in enumerate(dts):
                d = np.array(dt['keypoints'])
                xd = d[0::3]; yd = d[1::3]
                if k1>0:
                    # measure the per-keypoint distance if keypoints visible
                    dx = xd - xg
                    dy = yd - yg
                else:
                    # measure minimum distance to keypoints in (x0,y0) & (x1,y1)
                    z = np.zeros((k))
                    dx = np.max((z, x0-xd),axis=0)+np.max((z, xd-x1),axis=0)
                    dy = np.max((z, y0-yd),axis=0)+np.max((z, yd-y1),axis=0)
                e = (dx**2 + dy**2) / vars / (gt['area']+np.spacing(1)) / 2
                if k1 > 0:
                    e=e[vg > 0]
                ious[i, j] = np.sum(np.exp(-e)) / e.shape[0]
        return ious

核定部分

e = (dx**2 + dy**2) / vars / (gt['area']+np.spacing(1)) / 2

与 nms 计算 oks 时差别仅在于计算面积的时候,注意两者都没有进行面积的平方

e = (dx**2 + dy**2) / vars / ((a_g+a_d[n_d]) / 2+np.spacing(1)) / 2


在这里插入图片描述

参考

在这里插入图片描述
评价指标代码:cocodataset / cocoapi

在这里插入图片描述

  • Original Dts:OKS = 0.9 下的 PR(类比 AP 0.9)
  • Miss:漏检的(被纠正,距离超过了 sigama)
  • Swap:不同人的同一部位的错检(被纠正)
  • Inversion:同一人不同部位的错检(被纠正)
  • Jitter:小的定位错误,在 GT 覆盖的范围外附近(被纠正)
  • Opt. Score:
    在这里插入图片描述
  • FP:多检测了
  • FN:所有其他的错误(漏检了)

上面分析可以看出,该方法的错误 dominated by imperfect localization, mostly jitter errors, and missed detections

  • 9
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值