use a condition to notify when object detection has run

This commit is contained in:
blakeblackshear 2019-02-17 12:32:19 -06:00
parent 957bd2adeb
commit 92e1833def

View File

@ -93,14 +93,19 @@ def detect_objects(cropped_frame, sess, detection_graph, region_size, region_x_o
return objects return objects
class ObjectParser(threading.Thread): class ObjectParser(threading.Thread):
def __init__(self, object_arrays): def __init__(self, objects_changed, object_arrays):
threading.Thread.__init__(self) threading.Thread.__init__(self)
self._objects_changed = objects_changed
self._object_arrays = object_arrays self._object_arrays = object_arrays
def run(self): def run(self):
global DETECTED_OBJECTS global DETECTED_OBJECTS
while True: while True:
detected_objects = [] detected_objects = []
# wait until object detection has run
with self._objects_changed:
self._objects_changed.wait()
for object_array in self._object_arrays: for object_array in self._object_arrays:
object_index = 0 object_index = 0
while(object_index < 60 and object_array[object_index] > 0): while(object_index < 60 and object_array[object_index] > 0):
@ -115,7 +120,6 @@ class ObjectParser(threading.Thread):
}) })
object_index += 6 object_index += 6
DETECTED_OBJECTS = detected_objects DETECTED_OBJECTS = detected_objects
time.sleep(0.1)
class MqttPublisher(threading.Thread): class MqttPublisher(threading.Thread):
def __init__(self, host, topic_prefix, object_classes, motion_flags): def __init__(self, host, topic_prefix, object_classes, motion_flags):
threading.Thread.__init__(self) threading.Thread.__init__(self)
@ -201,6 +205,8 @@ def main():
frame_lock = mp.Lock() frame_lock = mp.Lock()
# Condition for notifying that a new frame is ready # Condition for notifying that a new frame is ready
frame_ready = mp.Condition() frame_ready = mp.Condition()
# Condition for notifying that object detection ran
objects_changed = mp.Condition()
# shape current frame so it can be treated as an image # shape current frame so it can be treated as an image
frame_arr = tonumpyarray(shared_arr).reshape(frame_shape) frame_arr = tonumpyarray(shared_arr).reshape(frame_shape)
@ -216,6 +222,7 @@ def main():
shared_frame_time, shared_frame_time,
frame_lock, frame_ready, frame_lock, frame_ready,
region['motion_detected'], region['motion_detected'],
objects_changed,
frame_shape, frame_shape,
region['size'], region['x_offset'], region['y_offset'])) region['size'], region['x_offset'], region['y_offset']))
detection_process.daemon = True detection_process.daemon = True
@ -232,7 +239,7 @@ def main():
motion_process.daemon = True motion_process.daemon = True
motion_processes.append(motion_process) motion_processes.append(motion_process)
object_parser = ObjectParser([region['output_array'] for region in regions]) object_parser = ObjectParser(objects_changed, [region['output_array'] for region in regions])
object_parser.start() object_parser.start()
mqtt_publisher = MqttPublisher(MQTT_HOST, MQTT_TOPIC_PREFIX, mqtt_publisher = MqttPublisher(MQTT_HOST, MQTT_TOPIC_PREFIX,
@ -342,7 +349,8 @@ def fetch_frames(shared_arr, shared_frame_time, frame_lock, frame_ready, frame_s
video.release() video.release()
# do the actual object detection # do the actual object detection
def process_frames(shared_arr, shared_output_arr, shared_frame_time, frame_lock, frame_ready, motion_detected, frame_shape, region_size, region_x_offset, region_y_offset): def process_frames(shared_arr, shared_output_arr, shared_frame_time, frame_lock, frame_ready,
motion_detected, objects_changed, frame_shape, region_size, region_x_offset, region_y_offset):
debug = True debug = True
# shape shared input array into frame for processing # shape shared input array into frame for processing
arr = tonumpyarray(shared_arr).reshape(frame_shape) arr = tonumpyarray(shared_arr).reshape(frame_shape)
@ -380,6 +388,8 @@ def process_frames(shared_arr, shared_output_arr, shared_frame_time, frame_lock,
objects = detect_objects(cropped_frame_rgb, sess, detection_graph, region_size, region_x_offset, region_y_offset, True) objects = detect_objects(cropped_frame_rgb, sess, detection_graph, region_size, region_x_offset, region_y_offset, True)
# copy the detected objects to the output array, filling the array when needed # copy the detected objects to the output array, filling the array when needed
shared_output_arr[:] = objects + [0.0] * (60-len(objects)) shared_output_arr[:] = objects + [0.0] * (60-len(objects))
with objects_changed:
objects_changed.notify_all()
# do the actual motion detection # do the actual motion detection
def detect_motion(shared_arr, shared_frame_time, frame_lock, frame_ready, motion_detected, frame_shape, region_size, region_x_offset, region_y_offset, min_motion_area, debug): def detect_motion(shared_arr, shared_frame_time, frame_lock, frame_ready, motion_detected, frame_shape, region_size, region_x_offset, region_y_offset, min_motion_area, debug):