17
17
from frigate .track import ObjectTracker
18
18
from frigate .types import PTZMetricsTypes
19
19
from frigate .util .image import intersection_over_union
20
- from frigate .util .object import average_boxes
20
+ from frigate .util .object import average_boxes , median_of_boxes
21
21
22
22
logger = logging .getLogger (__name__ )
23
23
24
24
25
- THRESHOLD_STATIONARY_IOU_AVERAGE = 0.6
25
+ THRESHOLD_ACTIVE_IOU = 0.2
26
+ THRESHOLD_STATIONARY_IOU = 0.6
26
27
MAX_STATIONARY_HISTORY = 10
27
28
28
29
@@ -146,6 +147,7 @@ def deregister(self, id, track_id):
146
147
# tracks the current position of the object based on the last N bounding boxes
147
148
# returns False if the object has moved outside its previous position
148
149
def update_position (self , id : str , box : list [int , int , int , int ]):
150
+ xmin , ymin , xmax , ymax = box
149
151
position = self .positions [id ]
150
152
self .stationary_box_history [id ].append (box )
151
153
@@ -158,11 +160,9 @@ def update_position(self, id: str, box: list[int, int, int, int]):
158
160
box , average_boxes (self .stationary_box_history [id ])
159
161
)
160
162
161
- xmin , ymin , xmax , ymax = box
162
-
163
- # if the iou drops below the threshold
164
- # assume the object has moved to a new position and reset the computed box
165
- if avg_iou < THRESHOLD_STATIONARY_IOU_AVERAGE :
163
+ # object has minimal or zero iou
164
+ # assume object is active
165
+ if avg_iou < THRESHOLD_ACTIVE_IOU :
166
166
self .positions [id ] = {
167
167
"xmins" : [xmin ],
168
168
"ymins" : [ymin ],
@@ -175,6 +175,33 @@ def update_position(self, id: str, box: list[int, int, int, int]):
175
175
}
176
176
return False
177
177
178
+ # object has iou below threshold, check median to reduce outliers
179
+ if avg_iou < THRESHOLD_STATIONARY_IOU :
180
+ median_iou = intersection_over_union (
181
+ (
182
+ position ["xmin" ],
183
+ position ["ymin" ],
184
+ position ["xmax" ],
185
+ position ["ymax" ],
186
+ ),
187
+ median_of_boxes (self .stationary_box_history [id ]),
188
+ )
189
+
190
+ # if the median iou drops below the threshold
191
+ # assume object is no longer stationary
192
+ if median_iou < THRESHOLD_STATIONARY_IOU :
193
+ self .positions [id ] = {
194
+ "xmins" : [xmin ],
195
+ "ymins" : [ymin ],
196
+ "xmaxs" : [xmax ],
197
+ "ymaxs" : [ymax ],
198
+ "xmin" : xmin ,
199
+ "ymin" : ymin ,
200
+ "xmax" : xmax ,
201
+ "ymax" : ymax ,
202
+ }
203
+ return False
204
+
178
205
# if there are less than 10 entries for the position, add the bounding box
179
206
# and recompute the position box
180
207
if len (position ["xmins" ]) < 10 :
0 commit comments