move zone config under each camera

This commit is contained in:
Blake Blackshear 2020-09-14 21:03:18 -05:00
parent 005e188d38
commit fdc8bbf72d
3 changed files with 43 additions and 47 deletions

View File

@ -76,39 +76,6 @@ objects:
min_score: 0.5 min_score: 0.5
threshold: 0.85 threshold: 0.85
zones:
#################
# Name of the zone
################
front_steps:
front_door:
####################
# For each camera, a list of x,y coordinates to define the polygon of the zone. The top
# left corner is 0,0. Can also be a comma separated string of all x,y coordinates combined.
# The same zone can exist across multiple cameras if they have overlapping FOVs.
# An object is determined to be in the zone based on whether or not the bottom center
# of it's bounding box is within the polygon. The polygon must have at least 3 points.
# Coordinates can be generated at https://www.image-map.net/
####################
coordinates:
- 545,1077
- 747,939
- 788,805
################
# Zone level object filters. These are applied in addition to the global and camera filters
# and should be more restrictive than the global and camera filters. The global and camera
# filters are applied upstream.
################
filters:
person:
min_area: 5000
max_area: 100000
threshold: 0.8
driveway:
front_door:
coordinates: 545,1077,747,939,788,805
yard:
cameras: cameras:
back: back:
ffmpeg: ffmpeg:
@ -169,6 +136,37 @@ cameras:
# crop_to_region: True # crop_to_region: True
# snapshot_height: 300 # snapshot_height: 300
################
# Zones
################
zones:
#################
# Name of the zone
################
front_steps:
####################
# A list of x,y coordinates to define the polygon of the zone. The top
# left corner is 0,0. Can also be a comma separated string of all x,y coordinates combined.
# The same zone name can exist across multiple cameras if they have overlapping FOVs.
# An object is determined to be in the zone based on whether or not the bottom center
# of it's bounding box is within the polygon. The polygon must have at least 3 points.
# Coordinates can be generated at https://www.image-map.net/
####################
coordinates:
- 545,1077
- 747,939
- 788,805
################
# Zone level object filters. These are applied in addition to the global and camera filters
# and should be more restrictive than the global and camera filters. The global and camera
# filters are applied upstream.
################
filters:
person:
min_area: 5000
max_area: 100000
threshold: 0.8
################ ################
# This will save a clip for each tracked object by frigate along with a json file that contains # This will save a clip for each tracked object by frigate along with a json file that contains
# data related to the tracked object. This works by telling ffmpeg to write video segments to /cache # data related to the tracked object. This works by telling ffmpeg to write video segments to /cache

View File

@ -182,7 +182,7 @@ def main():
'show_timestamp': config.get('snapshots', {}).get('show_timestamp', True), 'show_timestamp': config.get('snapshots', {}).get('show_timestamp', True),
'draw_zones': config.get('snapshots', {}).get('draw_zones', False) 'draw_zones': config.get('snapshots', {}).get('draw_zones', False)
} }
config['zones'] = {} config['zones'] = config.get('zones', {})
# Queue for cameras to push tracked objects to # Queue for cameras to push tracked objects to
tracked_objects_queue = mp.Queue() tracked_objects_queue = mp.Queue()
@ -293,7 +293,7 @@ def main():
event_processor = EventProcessor(CONFIG['cameras'], camera_processes, '/cache', '/clips', event_queue, stop_event) event_processor = EventProcessor(CONFIG['cameras'], camera_processes, '/cache', '/clips', event_queue, stop_event)
event_processor.start() event_processor.start()
object_processor = TrackedObjectProcessor(CONFIG['cameras'], CONFIG.get('zones', {}), client, MQTT_TOPIC_PREFIX, tracked_objects_queue, event_queue, stop_event) object_processor = TrackedObjectProcessor(CONFIG['cameras'], client, MQTT_TOPIC_PREFIX, tracked_objects_queue, event_queue, stop_event)
object_processor.start() object_processor.start()
camera_watchdog = CameraWatchdog(camera_processes, CONFIG['cameras'], tflite_process, tracked_objects_queue, plasma_process, stop_event) camera_watchdog = CameraWatchdog(camera_processes, CONFIG['cameras'], tflite_process, tracked_objects_queue, plasma_process, stop_event)

View File

@ -230,10 +230,9 @@ class CameraState():
class TrackedObjectProcessor(threading.Thread): class TrackedObjectProcessor(threading.Thread):
def __init__(self, camera_config, zone_config, client, topic_prefix, tracked_objects_queue, event_queue, stop_event): def __init__(self, camera_config, client, topic_prefix, tracked_objects_queue, event_queue, stop_event):
threading.Thread.__init__(self) threading.Thread.__init__(self)
self.camera_config = camera_config self.camera_config = camera_config
self.zone_config = zone_config
self.client = client self.client = client
self.topic_prefix = topic_prefix self.topic_prefix = topic_prefix
self.tracked_objects_queue = tracked_objects_queue self.tracked_objects_queue = tracked_objects_queue
@ -299,25 +298,24 @@ class TrackedObjectProcessor(threading.Thread):
self.zone_data = defaultdict(lambda: defaultdict(lambda: set())) self.zone_data = defaultdict(lambda: defaultdict(lambda: set()))
# set colors for zones # set colors for zones
all_zone_names = set([zone for config in self.camera_config.values() for zone in config['zones'].keys()])
zone_colors = {} zone_colors = {}
colors = plt.cm.get_cmap('tab10', len(self.zone_config.keys())) colors = plt.cm.get_cmap('tab10', len(all_zone_names))
for i, zone in enumerate(self.zone_config.keys()): for i, zone in enumerate(all_zone_names):
zone_colors[zone] = tuple(int(round(255 * c)) for c in colors(i)[:3]) zone_colors[zone] = tuple(int(round(255 * c)) for c in colors(i)[:3])
# create zone contours # create zone contours
for zone_name, config in zone_config.items(): for camera_config in self.camera_config.values():
for camera, camera_zone_config in config.items(): for zone_name, zone_config in camera_config['zones'].items():
camera_zone = {} zone_config['color'] = zone_colors[zone_name]
camera_zone['color'] = zone_colors[zone_name] coordinates = zone_config['coordinates']
coordinates = camera_zone_config['coordinates']
if isinstance(coordinates, list): if isinstance(coordinates, list):
camera_zone['contour'] = np.array([[int(p.split(',')[0]), int(p.split(',')[1])] for p in coordinates]) zone_config['contour'] = np.array([[int(p.split(',')[0]), int(p.split(',')[1])] for p in coordinates])
elif isinstance(coordinates, str): elif isinstance(coordinates, str):
points = coordinates.split(',') points = coordinates.split(',')
camera_zone['contour'] = np.array([[int(points[i]), int(points[i+1])] for i in range(0, len(points), 2)]) zone_config['contour'] = np.array([[int(points[i]), int(points[i+1])] for i in range(0, len(points), 2)])
else: else:
print(f"Unable to parse zone coordinates for {zone_name} - {camera}") print(f"Unable to parse zone coordinates for {zone_name} - {camera}")
self.camera_config[camera]['zones'][zone_name] = camera_zone
def get_best(self, camera, label): def get_best(self, camera, label):
best_objects = self.camera_states[camera].best_objects best_objects = self.camera_states[camera].best_objects