diff --git a/docs/docs/guides/false_positives.md b/docs/docs/guides/false_positives.md index 6102fd63b..a77e9e9f3 100644 --- a/docs/docs/guides/false_positives.md +++ b/docs/docs/guides/false_positives.md @@ -3,11 +3,7 @@ id: false_positives title: Reducing false positives --- -Tune your object filters to adjust false positives: `min_area`, `max_area`, `min_ratio`, `max_ratio`, `min_score`, `threshold`. - -The `min_area` and `max_area` values are compared against the area (number of pixels) from a given detected object. If the area is outside this range, the object will be ignored as a false positive. This allows objects that must be too small or too large to be ignored. - -Similarly, the `min_ratio` and `max_ratio` values are compared against a given detected object's width/height ratio (in pixels). If the ratio is outside this range, the object will be ignored as a false positive. This allows objects that are proportionally too short-and-wide (higher ratio) or too tall-and-narrow (smaller ratio) to be ignored. +## Object Scores For object filters in your configuration, any single detection below `min_score` will be ignored as a false positive. `threshold` is based on the median of the history of scores (padded to 3 values) for a tracked object. Consider the following frames when `min_score` is set to 0.6 and threshold is set to 0.85: @@ -22,4 +18,32 @@ For object filters in your configuration, any single detection below `min_score` In frame 2, the score is below the `min_score` value, so Frigate ignores it and it becomes a 0.0. The computed score is the median of the score history (padding to at least 3 values), and only when that computed score crosses the `threshold` is the object marked as a true positive. That happens in frame 4 in the example. -If you're seeing false positives from stationary objects, please see Object Masks here: https://docs.frigate.video/configuration/masks/ +### Minimum Score + +Any detection below `min_score` will be immediately thrown out and never tracked because it is considered a false positive. If `min_score` is too low then false positives may be detected and tracked which can confuse the object tracker and may lead to wasted resources. If `min_score` is too high then lower scoring true positives like objects that are further away or partially occluded may be thrown out which can also confuse the tracker and cause valid events to be lost or disjointed. + +### Threshold + +`threshold` is used to determine that the object is a true positive. Once an object is detected with a score >= `threshold` object is considered a true positive. If `threshold` is too low then some higher scoring false positives may create an event. If `threshold` is too high then true positive events may be missed due to the object never scoring high enough. + +## Object Shape + +False positives can also be reduced by filtering a detection based on its shape. + +### Object Area + +`min_area` and `max_area` filter on the area of an objects bounding box in pixels and can be used to reduce false positives that are outside the range of expected sizes. For example when a leaf is detected as a dog or when a large tree is detected as a person, these can be reduced by adding a `min_area` / `max_area` filter. The recordings timeline can be used to determine the area of the bounding box in that frame by selecting a timeline item then mousing over or tapping the red box. + +### Object Proportions + +`min_ratio` and `max_ratio` filter on the ratio of width / height of an objects bounding box and can be used to reduce false positives. For example if a false positive is detected as very tall for a dog which is often wider, a `min_ratio` filter can be used to filter out these false positives. + +## Other Tools + +### Zones + +[Required zones](/configuration/zones.md) can be a great tool to reduce false positives that may be detected in the sky or other areas that are not of interest. The required zones will only create events for objects that enter the zone. + +### Object Masks + +[Object Filter Masks](/configuration/masks) are a last resort but can be useful when false positives are in the relatively same place but can not be filtered due to their size or shape. diff --git a/frigate/object_processing.py b/frigate/object_processing.py index 94855a398..64794361f 100644 --- a/frigate/object_processing.py +++ b/frigate/object_processing.py @@ -105,6 +105,10 @@ class TrackedObject: def __init__( self, camera, colormap, camera_config: CameraConfig, frame_cache, obj_data ): + # set the score history then remove as it is not part of object state + self.score_history = obj_data["score_history"] + del obj_data["score_history"] + self.obj_data = obj_data self.camera = camera self.colormap = colormap @@ -136,11 +140,8 @@ class TrackedObject: return self.computed_score < threshold def compute_score(self): - scores = self.score_history[:] - # pad with zeros if you dont have at least 3 scores - if len(scores) < 3: - scores += [0.0] * (3 - len(scores)) - return median(scores) + """get median of scores for object.""" + return median(self.score_history) def update(self, current_frame_time, obj_data): thumb_update = False @@ -151,6 +152,7 @@ class TrackedObject: self.score_history.append(0.0) else: self.score_history.append(obj_data["score"]) + # only keep the last 10 scores if len(self.score_history) > 10: self.score_history = self.score_history[-10:] diff --git a/frigate/track/norfair_tracker.py b/frigate/track/norfair_tracker.py index e11a38d44..058f246c7 100644 --- a/frigate/track/norfair_tracker.py +++ b/frigate/track/norfair_tracker.py @@ -97,6 +97,12 @@ class NorfairTracker(ObjectTracker): obj["start_time"] = obj["frame_time"] obj["motionless_count"] = 0 obj["position_changes"] = 0 + obj["score_history"] = [ + p.data["score"] + for p in next( + (o for o in self.tracker.tracked_objects if o.global_id == track_id) + ).past_detections + ] self.tracked_objects[id] = obj self.disappeared[id] = 0 self.positions[id] = {