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)))