| 
														
															@@ -102,12 +102,21 @@ class LocalObjectDetector(ObjectDetector): 
														 | 
													
												
											
												
													
														| 
														 | 
														
															          
														 | 
														
														 | 
														
															          
														 | 
													
												
											
												
													
														| 
														 | 
														
															         return detections 
														 | 
														
														 | 
														
															         return detections 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															-def run_detector(detection_queue, result_connections: Dict[str, Connection], avg_speed, start, tf_device): 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+def run_detector(detection_queue, out_events: Dict[str, mp.Event], avg_speed, start, tf_device): 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     print(f"Starting detection process: {os.getpid()}") 
														 | 
														
														 | 
														
															     print(f"Starting detection process: {os.getpid()}") 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     listen() 
														 | 
														
														 | 
														
															     listen() 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     frame_manager = SharedMemoryFrameManager() 
														 | 
														
														 | 
														
															     frame_manager = SharedMemoryFrameManager() 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     object_detector = LocalObjectDetector(tf_device=tf_device) 
														 | 
														
														 | 
														
															     object_detector = LocalObjectDetector(tf_device=tf_device) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    outputs = {} 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    for name in out_events.keys(): 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        out_shm = mp.shared_memory.SharedMemory(name=f"out-{name}", create=False) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        out_np = np.ndarray((20,6), dtype=np.float32, buffer=out_shm.buf) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        outputs[name] = { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+            'shm': out_shm, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+            'np': out_np 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+     
														 | 
													
												
											
												
													
														| 
														 | 
														
															     while True: 
														 | 
														
														 | 
														
															     while True: 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         connection_id = detection_queue.get() 
														 | 
														
														 | 
														
															         connection_id = detection_queue.get() 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         input_frame = frame_manager.get(connection_id, (1,300,300,3)) 
														 | 
														
														 | 
														
															         input_frame = frame_manager.get(connection_id, (1,300,300,3)) 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -115,20 +124,21 @@ def run_detector(detection_queue, result_connections: Dict[str, Connection], avg 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         if input_frame is None: 
														 | 
														
														 | 
														
															         if input_frame is None: 
														 | 
													
												
											
												
													
														| 
														 | 
														
															             continue 
														 | 
														
														 | 
														
															             continue 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															-        # detect and put the output in the plasma store 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        # detect and send the output 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         start.value = datetime.datetime.now().timestamp() 
														 | 
														
														 | 
														
															         start.value = datetime.datetime.now().timestamp() 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         # TODO: what is the overhead for pickling this result vs writing back to shared memory? 
														 | 
														
														 | 
														
															         # TODO: what is the overhead for pickling this result vs writing back to shared memory? 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         #       I could try using an Event() and waiting in the other process before looking in memory... 
														 | 
														
														 | 
														
															         #       I could try using an Event() and waiting in the other process before looking in memory... 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         detections = object_detector.detect_raw(input_frame) 
														 | 
														
														 | 
														
															         detections = object_detector.detect_raw(input_frame) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-        result_connections[connection_id].send(detections) 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         duration = datetime.datetime.now().timestamp()-start.value 
														 | 
														
														 | 
														
															         duration = datetime.datetime.now().timestamp()-start.value 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        outputs[connection_id]['np'][:] = detections[:] 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        out_events[connection_id].set() 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         start.value = 0.0 
														 | 
														
														 | 
														
															         start.value = 0.0 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															         avg_speed.value = (avg_speed.value*9 + duration)/10 
														 | 
														
														 | 
														
															         avg_speed.value = (avg_speed.value*9 + duration)/10 
														 | 
													
												
											
												
													
														| 
														 | 
														
															          
														 | 
														
														 | 
														
															          
														 | 
													
												
											
												
													
														| 
														 | 
														
															 class EdgeTPUProcess(): 
														 | 
														
														 | 
														
															 class EdgeTPUProcess(): 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-    def __init__(self, result_connections, tf_device=None): 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-        self.result_connections = result_connections 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    def __init__(self, out_events, tf_device=None): 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        self.out_events = out_events 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         self.detection_queue = mp.Queue() 
														 | 
														
														 | 
														
															         self.detection_queue = mp.Queue() 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         self.avg_inference_speed = mp.Value('d', 0.01) 
														 | 
														
														 | 
														
															         self.avg_inference_speed = mp.Value('d', 0.01) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         self.detection_start = mp.Value('d', 0.0) 
														 | 
														
														 | 
														
															         self.detection_start = mp.Value('d', 0.0) 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -149,19 +159,21 @@ class EdgeTPUProcess(): 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         self.detection_start.value = 0.0 
														 | 
														
														 | 
														
															         self.detection_start.value = 0.0 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         if (not self.detect_process is None) and self.detect_process.is_alive(): 
														 | 
														
														 | 
														
															         if (not self.detect_process is None) and self.detect_process.is_alive(): 
														 | 
													
												
											
												
													
														| 
														 | 
														
															             self.stop() 
														 | 
														
														 | 
														
															             self.stop() 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-        self.detect_process = mp.Process(target=run_detector, args=(self.detection_queue, self.result_connections, self.avg_inference_speed, self.detection_start, self.tf_device)) 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        self.detect_process = mp.Process(target=run_detector, args=(self.detection_queue, self.out_events, self.avg_inference_speed, self.detection_start, self.tf_device)) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         self.detect_process.daemon = True 
														 | 
														
														 | 
														
															         self.detect_process.daemon = True 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         self.detect_process.start() 
														 | 
														
														 | 
														
															         self.detect_process.start() 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															 class RemoteObjectDetector(): 
														 | 
														
														 | 
														
															 class RemoteObjectDetector(): 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-    def __init__(self, name, labels, detection_queue, result_connection: Connection): 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    def __init__(self, name, labels, detection_queue, event): 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         self.labels = load_labels(labels) 
														 | 
														
														 | 
														
															         self.labels = load_labels(labels) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         self.name = name 
														 | 
														
														 | 
														
															         self.name = name 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         self.fps = EventsPerSecond() 
														 | 
														
														 | 
														
															         self.fps = EventsPerSecond() 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         self.detection_queue = detection_queue 
														 | 
														
														 | 
														
															         self.detection_queue = detection_queue 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-        self.result_connection = result_connection 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        self.event = event 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         self.shm = mp.shared_memory.SharedMemory(name=self.name, create=True, size=300*300*3) 
														 | 
														
														 | 
														
															         self.shm = mp.shared_memory.SharedMemory(name=self.name, create=True, size=300*300*3) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         self.np_shm = np.ndarray((1,300,300,3), dtype=np.uint8, buffer=self.shm.buf) 
														 | 
														
														 | 
														
															         self.np_shm = np.ndarray((1,300,300,3), dtype=np.uint8, buffer=self.shm.buf) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        self.out_shm = mp.shared_memory.SharedMemory(name=f"out-{self.name}", create=True, size=20*6*4) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        self.out_np_shm = np.ndarray((20,6), dtype=np.float32, buffer=self.out_shm.buf) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															      
														 | 
														
														 | 
														
															      
														 | 
													
												
											
												
													
														| 
														 | 
														
															     def detect(self, tensor_input, threshold=.4): 
														 | 
														
														 | 
														
															     def detect(self, tensor_input, threshold=.4): 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         detections = [] 
														 | 
														
														 | 
														
															         detections = [] 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -169,13 +181,16 @@ class RemoteObjectDetector(): 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         # copy input to shared memory 
														 | 
														
														 | 
														
															         # copy input to shared memory 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         # TODO: what if I just write it there in the first place? 
														 | 
														
														 | 
														
															         # TODO: what if I just write it there in the first place? 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         self.np_shm[:] = tensor_input[:] 
														 | 
														
														 | 
														
															         self.np_shm[:] = tensor_input[:] 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        self.event.clear() 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         self.detection_queue.put(self.name) 
														 | 
														
														 | 
														
															         self.detection_queue.put(self.name) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-        if self.result_connection.poll(10): 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-            raw_detections = self.result_connection.recv() 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-        else: 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-            return detections 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        self.event.wait() 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+         
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        # if self.result_connection.poll(10): 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        #     raw_detections = self.result_connection.recv() 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        # else: 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        #     return detections 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															-        for d in raw_detections: 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        for d in self.out_np_shm: 
														 | 
													
												
											
												
													
														| 
														 | 
														
															             if d[1] < threshold: 
														 | 
														
														 | 
														
															             if d[1] < threshold: 
														 | 
													
												
											
												
													
														| 
														 | 
														
															                 break 
														 | 
														
														 | 
														
															                 break 
														 | 
													
												
											
												
													
														| 
														 | 
														
															             detections.append(( 
														 | 
														
														 | 
														
															             detections.append(( 
														 |