2019-02-26 03:27:02 +01:00
|
|
|
import json
|
2019-07-14 15:31:21 +02:00
|
|
|
import cv2
|
2019-02-26 03:27:02 +01:00
|
|
|
import threading
|
2019-12-23 13:01:32 +01:00
|
|
|
import prctl
|
2019-12-14 22:18:21 +01:00
|
|
|
from collections import Counter, defaultdict
|
2019-12-31 21:59:22 +01:00
|
|
|
import itertools
|
2019-02-26 03:27:02 +01:00
|
|
|
|
|
|
|
class MqttObjectPublisher(threading.Thread):
|
2020-01-10 03:53:04 +01:00
|
|
|
def __init__(self, client, topic_prefix, camera):
|
2019-02-26 03:27:02 +01:00
|
|
|
threading.Thread.__init__(self)
|
|
|
|
self.client = client
|
|
|
|
self.topic_prefix = topic_prefix
|
2020-01-10 03:53:04 +01:00
|
|
|
self.camera = camera
|
2019-02-26 03:27:02 +01:00
|
|
|
|
|
|
|
def run(self):
|
2020-01-10 03:53:04 +01:00
|
|
|
prctl.set_name(self.__class__.__name__)
|
2019-12-14 22:18:21 +01:00
|
|
|
current_object_status = defaultdict(lambda: 'OFF')
|
2019-02-26 03:27:02 +01:00
|
|
|
while True:
|
2020-01-10 03:53:04 +01:00
|
|
|
# wait until objects have been tracked
|
|
|
|
with self.camera.objects_tracked:
|
|
|
|
self.camera.objects_tracked.wait()
|
2019-02-26 03:27:02 +01:00
|
|
|
|
2020-01-10 03:53:04 +01:00
|
|
|
# count objects with more than 2 entries in history by type
|
2019-12-14 22:18:21 +01:00
|
|
|
obj_counter = Counter()
|
2020-01-10 03:53:04 +01:00
|
|
|
for obj in self.camera.object_tracker.tracked_objects.values():
|
|
|
|
if len(obj['history']) > 1:
|
|
|
|
obj_counter[obj['name']] += 1
|
2019-12-14 22:18:21 +01:00
|
|
|
|
|
|
|
# report on detected objects
|
2020-01-10 03:53:04 +01:00
|
|
|
for obj_name, count in obj_counter.items():
|
|
|
|
new_status = 'ON' if count > 0 else 'OFF'
|
2019-12-14 22:18:21 +01:00
|
|
|
if new_status != current_object_status[obj_name]:
|
|
|
|
current_object_status[obj_name] = new_status
|
|
|
|
self.client.publish(self.topic_prefix+'/'+obj_name, new_status, retain=False)
|
2019-12-21 03:02:27 +01:00
|
|
|
# send the snapshot over mqtt if we have it as well
|
2020-01-10 03:53:04 +01:00
|
|
|
if obj_name in self.camera.best_frames.best_frames:
|
|
|
|
best_frame = cv2.cvtColor(self.camera.best_frames.best_frames[obj_name], cv2.COLOR_RGB2BGR)
|
2019-12-23 13:01:32 +01:00
|
|
|
ret, jpg = cv2.imencode('.jpg', best_frame)
|
2019-12-14 22:18:21 +01:00
|
|
|
if ret:
|
|
|
|
jpg_bytes = jpg.tobytes()
|
|
|
|
self.client.publish(self.topic_prefix+'/'+obj_name+'/snapshot', jpg_bytes, retain=True)
|
|
|
|
|
|
|
|
# expire any objects that are ON and no longer detected
|
|
|
|
expired_objects = [obj_name for obj_name, status in current_object_status.items() if status == 'ON' and not obj_name in obj_counter]
|
|
|
|
for obj_name in expired_objects:
|
2019-12-21 02:56:12 +01:00
|
|
|
current_object_status[obj_name] = 'OFF'
|
2020-01-12 14:14:42 +01:00
|
|
|
self.client.publish(self.topic_prefix+'/'+obj_name, 'OFF', retain=False)
|
|
|
|
# send updated snapshot snapshot over mqtt if we have it as well
|
|
|
|
if obj_name in self.camera.best_frames.best_frames:
|
|
|
|
best_frame = cv2.cvtColor(self.camera.best_frames.best_frames[obj_name], cv2.COLOR_RGB2BGR)
|
|
|
|
ret, jpg = cv2.imencode('.jpg', best_frame)
|
|
|
|
if ret:
|
|
|
|
jpg_bytes = jpg.tobytes()
|
|
|
|
self.client.publish(self.topic_prefix+'/'+obj_name+'/snapshot', jpg_bytes, retain=True)
|