-
Notifications
You must be signed in to change notification settings - Fork 25
/
utils.py
171 lines (136 loc) · 5.54 KB
/
utils.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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
import numpy as np
from scipy import stats
COCO_INSTANCE_CATEGORY_NAMES = [
'__background__', 'person', 'bicycle', 'car', 'motorcycle', 'airplane', 'bus',
'train', 'truck', 'boat', 'traffic light', 'fire hydrant', 'N/A', 'stop sign',
'parking meter', 'bench', 'bird', 'cat', 'dog', 'horse', 'sheep', 'cow',
'elephant', 'bear', 'zebra', 'giraffe', 'N/A', 'backpack', 'umbrella', 'N/A', 'N/A',
'handbag', 'tie', 'suitcase', 'frisbee', 'skis', 'snowboard', 'sports ball',
'kite', 'baseball bat', 'baseball glove', 'skateboard', 'surfboard', 'tennis racket',
'bottle', 'N/A', 'wine glass', 'cup', 'fork', 'knife', 'spoon', 'bowl',
'banana', 'apple', 'sandwich', 'orange', 'broccoli', 'carrot', 'hot dog', 'pizza',
'donut', 'cake', 'chair', 'couch', 'potted plant', 'bed', 'N/A', 'dining table',
'N/A', 'N/A', 'toilet', 'N/A', 'tv', 'laptop', 'mouse', 'remote', 'keyboard', 'cell phone',
'microwave', 'oven', 'toaster', 'sink', 'refrigerator', 'N/A', 'book',
'clock', 'vase', 'scissors', 'teddy bear', 'hair drier', 'toothbrush'
]
ROIs = {
'mall': (-2., 8., -7., 7.),
'grand_central': (-7., 25., 0., 34.),
'oxford_town': (0., 14., 5., 28.),
}
def decode_data(data, roi):
"""
- decode the raw data w.r.t. the defined roi.
:param data:
:param roi:
:return:
"""
x_min, x_max, y_min, y_max = roi
area = (x_max - x_min) * (y_max - y_min)
density = []
ts_inference = []
pts_roi_all_frame = []
inds_frame = []
nums_ped = []
for i_frame, t_inference, pts in data:
count_in = 0
count_out = 0
pts_roi = []
for pt in pts:
if x_min < pt[0] < x_max and y_min < pt[1] < y_max:
count_in += 1
pts_roi.append(pt)
else:
count_out += 1
pts_roi_all_frame.append(np.array(pts_roi))
density.append(count_in / area)
ts_inference.append(t_inference)
inds_frame.append(i_frame)
nums_ped.append(count_in)
# print('frame %d - num. of ped inside roi: %d, outside: %d' % (i_frame, count_in, count_out))
return np.array(inds_frame), np.array(ts_inference), pts_roi_all_frame, np.array(density), nums_ped
def count_violation_pairs(pts_all_frames, dist=2.0):
counts = []
for pts in pts_all_frames:
pairs = find_violation(pts, dist)
counts.append(len(pairs))
return np.array(counts)
def find_violation(pts, dist=2.0):
"""
:param pts: positions of all pedestrians in a single frame
:param dist: social distance
:return: a list of index pairs indicating two pedestrians who are violating social distancing
"""
n = len(pts) # number of pedestrians
pairs = []
for i in np.arange(0, n, 1):
for j in np.arange(i+1, n, 1):
if np.linalg.norm(pts[i] - pts[j]) < dist:
pairs.append((i, j))
return pairs
def cal_min_dists_all_frame(pts_all_frame):
all_min_dists = []
avg_min_dists = []
min_min_dists = []
for pts in pts_all_frame:
min_dists = cal_min_dists(pts)
all_min_dists.append(min_dists)
min_min_dists.append(min(min_dists) if len(min_dists) > 0 else None)
avg_min_dists.append(sum(min_dists) / len(min_dists) if len(min_dists) > 0 else None)
all_min_dists = sum(all_min_dists, [])
return all_min_dists, np.array(min_min_dists), np.array(avg_min_dists)
def cal_min_dists(pts):
"""
:param pts: positions of all pedestrians in a single frame
:return: a list of each pedestrian's min distances to other pedestrians
"""
n = len(pts)
ds_min = []
for i in range(n):
d_min = np.inf
for j in range(n):
# closest distance from pedestrian i to pedestrian j
if i != j and np.linalg.norm(pts[i] - pts[j]) < d_min:
d_min = np.linalg.norm(pts[i] - pts[j])
if d_min is not np.inf:
ds_min.append(d_min)
return ds_min
def custom_simple_linear_regression(xs, ys, x_select):
# reference 1: http://www2.stat.duke.edu/~tjl13/s101/slides/unit6lec3H.pdf
# reference 2: http://statweb.stanford.edu/~susan/courses/s141/horegconf.pdf
# assume: y = a + b*x + e
def pred_interval(x_star, prob=0.95):
se_pred = np.sqrt(variance * (1 + 1 / n + (x_star - xs.mean()) ** 2 / s_xx))
t_dist = stats.t.ppf([1 - (1 - prob)/2], len(xs) - 2)
y_hat = x_star * b + a
return float(y_hat - se_pred * t_dist), float(y_hat + se_pred * t_dist)
b, a, r_value, p_value, std_err = stats.linregress(xs, ys)
print('slope b = %.6f' % b)
print('intercept a = %.6f' % a)
print('r_value = %.6f' % r_value)
print('p_value = %.6f' % p_value)
print('se_a (from package) = %.6f' % std_err)
residuals = ys - (xs * b + a)
n = len(residuals)
variance = np.sum(residuals ** 2) / (n - 2)
s_xx = np.sum((xs - xs.mean()) ** 2)
s_x = s_xx / (n - 1)
se_a = np.sqrt(variance / s_xx)
print('se_a_ = %.6f' % se_a)
# se_intercept_wiki = std_err * np.sqrt(np.sum(xs ** 2) / n)
# print('se_intercept_wiki = %.6f' % se_intercept_wiki)
preds, lbs, ubs = [], [], [] # prediction interval
for x in np.arange(0, np.max(xs), 0.001):
lb, ub = pred_interval(x)
preds.append(x)
lbs.append(lb)
ubs.append(ub)
if x_select == 'x_intercept':
x_select = - a / b
elif x_select == 'y_intercept':
x_select = 0.0
else:
raise Exception
lb_select, ub_select = pred_interval(x_select)
return a, b, preds, lbs, ubs, x_select, lb_select, ub_select