pycocotools 插入自建評估方法

evaluate內部插入方法:

    def evaluate(self):
        '''
        Run per image evaluation on given images and store results (a list of dict) in self.evalImgs
        :return: None
        '''
        ~~~~
        self._paramsEval = copy.deepcopy(self.params)
        toc = time.time()
        print('DONE (t={:0.2f}s).'.format(toc-tic))
        
        # define mymetric
        self.myMetric()

定義自己方法:

    def myMetric(self):
        
        # 根據尺寸計算iou閾值
        def getIou(mwidth):
            if mwidth < 40:
                iou = 0.2
            elif mwidth < 120:
                iou = mwidth / 200.0
            elif mwidth < 420:
                iou = mwidth / 1500.0 + 0.52
            else:
                iou = 0.8
            return iou 

        # 將預測框和真實框進行匹配
        def evaluateImg(imgId, catId):
            maxDet = 100

            gt = self._gts[imgId, catId]
            dt = self._dts[imgId, catId]
            if len(gt) == 0 and len(dt) == 0:
                return None

            for g in gt:
                if g["ignore"]:
                    g["_ignore"] = 1
                else:
                    g["_ignore"] = 0

            gtind = np.argsort([g['_ignore'] for g in gt], kind='mergesort')
            gt = [gt[i] for i in gtind]
            dtind = np.argsort([-d['score'] for d in dt], kind='mergesort')
            dt = [dt[i] for i in dtind[0:maxDet]]
            iscrowd = [int(o['iscrowd']) for o in gt]

            ious = self.ious[imgId, catId][:, gtind] if len(self.ious[imgId, catId]) > 0 else self.ious[imgId, catId]

            G = len(gt)
            D = len(dt)
            gtm = np.zeros((1,G))
            dtm = np.zeros((1,D))
            gtIg = np.array([g['_ignore'] for g in gt])
            dtIg = np.zeros((1,D))

            if not len(ious) == 0:
                for dind, d in enumerate(dt):
                    iou = 0.0
                    m = -1
                    for gind, g in enumerate(gt):
                        if gtm[0,gind] > 0 and not iscrowd[gind]:
                            continue
                        if m > -1 and gtIg[m] == 0 and gtIg[gind] == 1:
                            break
                        if ious[dind, gind] <= getIou(min(g["bbox"][2], g["bbox"][3])):
                            continue
                        if ious[dind, gind] > iou:
                            iou = ious[dind, gind]
                            m = gind
                    if m == -1:
                        continue
                    dtIg[0,dind] = gtIg[m]
                    dtm[0,dind] = gt[m]["id"]
                    gtm[0,m] = d["id"]

            return {"image_id":imgId, "category_id":catId, "dtIds":[d["id"] for d in dt], "gtIds":[g["id"] for g in gt], "dtMatches":dtm, "gtMatches":gtm, "dtScores":[d["score"] for d in dt], 'gtIgnore':gtIg, 'dtIgnore':dtIg}

		# 累計計算map
        def accumulate(evalImgs):
            maxDet = 100
            p = self.params
            _pe = self._paramsEval

            k_list = [n for n,k in enumerate(p.catIds) if k in set(_pe.catIds)]
            i_list = [n for n,i in enumerate(p.imgIds)  if i in set(_pe.imgIds)]

            I0          = len(_pe.imgIds)
            K           = len(p.catIds) if p.useCats else 1
            R           = len(p.recThrs)
            precision   = -np.ones((1,R,K))
            recall      = -np.ones((1,K))
            scores      = -np.ones((1,R,K))


            for k,k0 in enumerate(k_list):
                Nk = k0 * I0
                E = [evalImgs[Nk + i] for i in i_list]
                E = [e for e in E if not e is None]
                if len(E) == 0:
                    continue

                dtScores = np.concatenate([e['dtScores'][0:maxDet] for e in E])
                inds = np.argsort(-dtScores, kind='mergesort')
                dtScoresSorted = dtScores[inds]
                dtm  = np.concatenate([e['dtMatches'][:,0:maxDet] for e in E], axis=1)[:,inds]
                dtIg = np.concatenate([e['dtIgnore'][:,0:maxDet]  for e in E], axis=1)[:,inds]
                gtIg = np.concatenate([e['gtIgnore'] for e in E])
                npig = np.count_nonzero(gtIg==0 )

                if npig == 0:
                    continue
                tps = np.logical_and(               dtm,  np.logical_not(dtIg) )
                fps = np.logical_and(np.logical_not(dtm), np.logical_not(dtIg) )
                tp_sum = np.cumsum(tps, axis=1).astype(dtype=np.float)
                fp_sum = np.cumsum(fps, axis=1).astype(dtype=np.float)

                for t, (tp, fp) in enumerate(zip(tp_sum, fp_sum)):
                    tp = np.array(tp)
                    fp = np.array(fp)
                    nd = len(tp)
                    rc = tp / npig
                    pr = tp / (fp+tp+np.spacing(1))
                    q  = np.zeros((R,))
                    ss = np.zeros((R,))
                    if nd:
                        recall[t,k] = rc[-1]
                    else:
                        recall[t,k] = 0

                    pr = pr.tolist(); q = q.tolist()
                    for i in range(nd-1, 0, -1):
                        if pr[i] > pr[i-1]:
                            pr[i-1] = pr[i]

                    inds = np.searchsorted(rc, p.recThrs, side='left')
                    try:
                        for ri, pi in enumerate(inds):
                            q[ri] = pr[pi]
                            ss[ri] = dtScoresSorted[pi]
                    except:       
                        pass
                    precision[t,:,k] = np.array(q)
                    scores[t,:,k] = np.array(ss)
                    
            return precision    

        imgIds = self.params.imgIds
        catIds = self.params.catIds

        evalImgs = [evaluateImg(imgId, catId) for catId in catIds for imgId in imgIds]
        s = accumulate(evalImgs)[0]
        sums = np.sum(s>-1, axis=0)
        s[s<=-1] = 0
        s = np.sum(s, axis=0)

		# label到權重的映射
        weight = {1:0.15, 2:0.09, 3:0.09, 4:0.05, 5:0.13, 6:0.05, 7:0.12, 8:0.13, 9:0.07, 10:0.12}
        w = []
        for cat in catIds:
            w.append(weight[cat])
        # print(s, s.shape)    
        print("###### catIds", catIds)
        print("###### category:", s/sums)
        print("###### weight:", np.sum(s/sums*np.array(w)))
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章