|
import numpy as np |
|
|
|
|
|
def bbox_iou(box1, box2, x1y1x2y2=True): |
|
if x1y1x2y2: |
|
mx = min(box1[0], box2[0]) |
|
Mx = max(box1[2], box2[2]) |
|
my = min(box1[1], box2[1]) |
|
My = max(box1[3], box2[3]) |
|
w1 = box1[2] - box1[0] |
|
h1 = box1[3] - box1[1] |
|
w2 = box2[2] - box2[0] |
|
h2 = box2[3] - box2[1] |
|
else: |
|
mx = min(float(box1[0]-box1[2]/2.0), float(box2[0]-box2[2]/2.0)) |
|
Mx = max(float(box1[0]+box1[2]/2.0), float(box2[0]+box2[2]/2.0)) |
|
my = min(float(box1[1]-box1[3]/2.0), float(box2[1]-box2[3]/2.0)) |
|
My = max(float(box1[1]+box1[3]/2.0), float(box2[1]+box2[3]/2.0)) |
|
w1 = box1[2] |
|
h1 = box1[3] |
|
w2 = box2[2] |
|
h2 = box2[3] |
|
uw = Mx - mx |
|
uh = My - my |
|
cw = w1 + w2 - uw |
|
ch = h1 + h2 - uh |
|
carea = 0 |
|
if cw <= 0 or ch <= 0: |
|
return 0.0 |
|
|
|
area1 = w1 * h1 |
|
area2 = w2 * h2 |
|
carea = cw * ch |
|
uarea = area1 + area2 - carea |
|
return carea/uarea |
|
|
|
|
|
def area2d(b): |
|
return (b[:,2]-b[:,0]+1)*(b[:,3]-b[:,1]+1) |
|
|
|
|
|
def overlap2d(b1, b2): |
|
xmin = np.maximum( b1[:,0], b2[:,0] ) |
|
xmax = np.minimum( b1[:,2]+1, b2[:,2]+1) |
|
width = np.maximum(0, xmax-xmin) |
|
ymin = np.maximum( b1[:,1], b2[:,1] ) |
|
ymax = np.minimum( b1[:,3]+1, b2[:,3]+1) |
|
height = np.maximum(0, ymax-ymin) |
|
return width*height |
|
|
|
|
|
def nms_3d(detections, overlap=0.5): |
|
|
|
if len(detections) == 0: |
|
return np.array([], dtype=np.int32) |
|
I = np.argsort([d[1] for d in detections]) |
|
indices = np.zeros(I.size, dtype=np.int32) |
|
counter = 0 |
|
while I.size>0: |
|
i = I[-1] |
|
indices[counter] = i |
|
counter += 1 |
|
ious = np.array([ iou3dt(detections[ii][0],detections[i][0]) for ii in I[:-1] ]) |
|
I = I[np.where(ious<=overlap)[0]] |
|
return indices[:counter] |
|
|
|
|
|
def iou3d(b1, b2): |
|
assert b1.shape[0] == b2.shape[0] |
|
assert np.all(b1[:,0] == b2[:,0]) |
|
o = overlap2d(b1[:,1:5],b2[:,1:5]) |
|
return np.mean( o/(area2d(b1[:,1:5])+area2d(b2[:,1:5])-o) ) |
|
|
|
|
|
def iou3dt(b1, b2): |
|
tmin = max(b1[0,0], b2[0,0]) |
|
tmax = min(b1[-1,0], b2[-1,0]) |
|
if tmax <= tmin: return 0.0 |
|
temporal_inter = tmax-tmin+1 |
|
temporal_union = max(b1[-1,0], b2[-1,0]) - min(b1[0,0], b2[0,0]) + 1 |
|
return iou3d( b1[np.where(b1[:,0]==tmin)[0][0]:np.where(b1[:,0]==tmax)[0][0]+1,:] , b2[np.where(b2[:,0]==tmin)[0][0]:np.where(b2[:,0]==tmax)[0][0]+1,:] ) * temporal_inter / temporal_union |
|
|
|
|
|
def voc_ap(pr, use_07_metric=False): |
|
""" ap = voc_ap(rec, prec, [use_07_metric]) |
|
Compute VOC AP given precision and recall. |
|
If use_07_metric is true, uses the |
|
VOC 07 11 point method (default:False). |
|
""" |
|
rec, prec = pr[:,1], pr[:,0] |
|
if use_07_metric: |
|
|
|
ap = 0. |
|
for t in np.arange(0., 1.1, 0.1): |
|
if np.sum(rec >= t) == 0: |
|
p = 0 |
|
else: |
|
p = np.max(prec[rec >= t]) |
|
ap = ap + p / 11. |
|
else: |
|
|
|
|
|
mrec = np.concatenate(([0.], rec, [1.])) |
|
mpre = np.concatenate(([0.], prec, [0.])) |
|
|
|
|
|
for i in range(mpre.size - 1, 0, -1): |
|
mpre[i - 1] = np.maximum(mpre[i - 1], mpre[i]) |
|
|
|
|
|
|
|
i = np.where(mrec[1:] != mrec[:-1])[0] |
|
|
|
|
|
ap = np.sum((mrec[i + 1] - mrec[i]) * mpre[i + 1]) |
|
return ap |
|
|