-
Notifications
You must be signed in to change notification settings - Fork 0
/
post_process.py
112 lines (79 loc) · 3.05 KB
/
post_process.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
import numpy as np
EPSILON = 1e-15
INF = 9e15
def get_iou(box1, box2):
# get the corrdinates of the intersection rectangle
rect_x1 = np.maximum(box1[0], box2[0])
rect_y1 = np.maximum(box1[1], box2[1])
rect_x2 = np.minimum(box1[2], box2[2])
rect_y2 = np.minimum(box1[3], box2[3])
# intersection area
inter_area = np.maximum((rect_x2 - rect_x1 + 1), 0) * \
np.maximum((rect_y2 - rect_y1 + 1), 0)
# union Area
b1_area = (box1[2] - box1[0] + 1) * (box1[3] - box1[1] + 1)
b2_area = (box2[2] - box2[0] + 1) * (box2[3] - box2[1] + 1)
# calculate iou
iou = inter_area / (b1_area + b2_area - inter_area)
return iou
def pair_distance(bboxA, scoreA, bboxB, scoreB):
# intersection over union score
iou = get_iou(bboxA, bboxB)
# confidence score
score = np.dot(scoreA, scoreB)
# distance is the inverse of similarity
# epsilon value prevents a divide by 0
distance = 1 / (iou * score + EPSILON)
return distance
def pair_positives(distances):
# initialize pair list
pairs = []
# continue while there are still unmatched axes
while distances.min() != INF:
# find the smallest distance
inds = np.where(distances == distances.min())
# check if either axis is 1
a, b = inds if len(inds[0]) == 1 else (inds[0][0], inds[1][0])
# record the results
a, b = int(a), int(b)
pairs.append((a, b))
# remove all other records in the same row and column
distances[a, :] = INF
distances[:, b] = INF
return pairs
def rescore_bbox(score, prev_score, count):
# calculate new historical vector score
score = float(score) / (count + 1) + \
float(prev_score) * count / (count + 1)
# increase consecutive frame count by one
count += 1
return score, count
def redetect(dets, prev_dets, idx, prev_idx):
# check if the first item is a string
if isinstance(prev_dets[idx][0], str):
count = 0
else:
count = prev_dets[idx][0]
# copy the previous bbox
new_bbox = dets[idx][2]
new_score, new_count = rescore_bbox(dets[idx][1],
prev_dets[prev_idx][1],
count)
return (new_count, new_score, new_bbox)
def post_process(dets, prev_dets):
# initialise the distance matrix
distances = np.zeros((len(dets), len(prev_dets)))
# cycle each combination of bboxs
for i, (_, score, bbox) in enumerate(dets, 0):
for j, (_, prev_score, prev_bbox) in enumerate(prev_dets, 0):
# record the distance between each pair
distances[i, j] = pair_distance(bbox,
float(score),
prev_bbox,
float(prev_score))
# find positive bbox pairs from the matrix
pairs = pair_positives(distances)
# create new dets
new_dets = [redetect(dets, prev_dets, idx, prev_idx)
for idx, prev_idx in pairs]
return new_dets