diff --git a/Dockerfile b/Dockerfile index f261fcb45..5fd62ec48 100755 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM ubuntu:18.04 +FROM ubuntu:20.04 LABEL maintainer "blakeb@blakeshome.com" ENV DEBIAN_FRONTEND=noninteractive @@ -11,27 +11,26 @@ RUN apt -qq update && apt -qq install --no-install-recommends -y \ # libcap-dev \ && add-apt-repository ppa:deadsnakes/ppa -y \ && apt -qq install --no-install-recommends -y \ - python3.7 \ - python3.7-dev \ + python3.8 \ + python3.8-dev \ python3-pip \ ffmpeg \ # VAAPI drivers for Intel hardware accel libva-drm2 libva2 i965-va-driver vainfo \ - && python3.7 -m pip install -U pip \ - && python3.7 -m pip install -U wheel setuptools \ - && python3.7 -m pip install -U \ + && python3.8 -m pip install -U pip \ + && python3.8 -m pip install -U wheel setuptools \ + && python3.8 -m pip install -U \ opencv-python-headless \ # python-prctl \ numpy \ imutils \ scipy \ psutil \ - && python3.7 -m pip install -U \ + && python3.8 -m pip install -U \ Flask \ paho-mqtt \ PyYAML \ matplotlib \ - pyarrow \ click \ && echo "deb https://packages.cloud.google.com/apt coral-edgetpu-stable main" > /etc/apt/sources.list.d/coral-edgetpu.list \ && wget -q -O - https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add - \ @@ -39,10 +38,10 @@ RUN apt -qq update && apt -qq install --no-install-recommends -y \ && echo "libedgetpu1-max libedgetpu/accepted-eula boolean true" | debconf-set-selections \ && apt -qq install --no-install-recommends -y \ libedgetpu1-max \ - ## Tensorflow lite (python 3.7 only) - && wget -q https://dl.google.com/coral/python/tflite_runtime-2.1.0.post1-cp37-cp37m-linux_x86_64.whl \ - && python3.7 -m pip install tflite_runtime-2.1.0.post1-cp37-cp37m-linux_x86_64.whl \ - && rm tflite_runtime-2.1.0.post1-cp37-cp37m-linux_x86_64.whl \ + ## Tensorflow lite + && wget -q https://dl.google.com/coral/python/tflite_runtime-2.1.0.post1-cp38-cp38-linux_x86_64.whl \ + && python3.8 -m pip install tflite_runtime-2.1.0.post1-cp38-cp38-linux_x86_64.whl \ + && rm tflite_runtime-2.1.0.post1-cp38-cp38-linux_x86_64.whl \ && rm -rf /var/lib/apt/lists/* \ && (apt-get autoremove -y; apt-get autoclean -y) @@ -60,4 +59,4 @@ COPY detect_objects.py . COPY benchmark.py . COPY process_clip.py . -CMD ["python3.7", "-u", "detect_objects.py"] +CMD ["python3.8", "-u", "detect_objects.py"] diff --git a/detect_objects.py b/detect_objects.py index c069d5c21..ce391b086 100644 --- a/detect_objects.py +++ b/detect_objects.py @@ -63,23 +63,13 @@ WEB_PORT = CONFIG.get('web_port', 5000) DEBUG = (CONFIG.get('debug', '0') == '1') TENSORFLOW_DEVICE = CONFIG.get('tensorflow_device') -def start_plasma_store(): - plasma_cmd = ['plasma_store', '-m', '400000000', '-s', '/tmp/plasma'] - plasma_process = sp.Popen(plasma_cmd, stdout=sp.DEVNULL, stderr=sp.DEVNULL) - time.sleep(1) - rc = plasma_process.poll() - if rc is not None: - return None - return plasma_process - class CameraWatchdog(threading.Thread): - def __init__(self, camera_processes, config, tflite_process, tracked_objects_queue, plasma_process, stop_event): + def __init__(self, camera_processes, config, tflite_process, tracked_objects_queue, stop_event): threading.Thread.__init__(self) self.camera_processes = camera_processes self.config = config self.tflite_process = tflite_process self.tracked_objects_queue = tracked_objects_queue - self.plasma_process = plasma_process self.stop_event = stop_event def run(self): @@ -93,12 +83,6 @@ class CameraWatchdog(threading.Thread): break now = datetime.datetime.now().timestamp() - - # check the plasma process - rc = self.plasma_process.poll() - if rc != None: - print(f"plasma_process exited unexpectedly with {rc}") - self.plasma_process = start_plasma_store() # check the detection process detection_start = self.tflite_process.detection_start.value @@ -172,8 +156,6 @@ def main(): client.connect(MQTT_HOST, MQTT_PORT, 60) client.loop_start() - plasma_process = start_plasma_store() - ## # Setup config defaults for cameras ## @@ -189,11 +171,16 @@ def main(): # Queue for clip processing event_queue = mp.Queue() + + # create the detection pipes + detection_pipes = {} + for name in CONFIG['cameras'].keys(): + detection_pipes[name] = mp.Pipe(duplex=False) # Start the shared tflite process - tflite_process = EdgeTPUProcess(TENSORFLOW_DEVICE) + tflite_process = EdgeTPUProcess(result_connections={ key:value[1] for (key,value) in detection_pipes.items() }, tf_device=TENSORFLOW_DEVICE) - # start the camera processes + # create the camera processes camera_processes = {} for name, config in CONFIG['cameras'].items(): # Merge the ffmpeg config with the global config @@ -236,6 +223,8 @@ def main(): frame_shape = (config['height'], config['width'], 3) else: frame_shape = get_frame_shape(ffmpeg_input) + + config['frame_shape'] = frame_shape frame_size = frame_shape[0] * frame_shape[1] * frame_shape[2] take_frame = config.get('take_frame', 1) @@ -275,12 +264,13 @@ def main(): } camera_process = mp.Process(target=track_camera, args=(name, config, frame_queue, frame_shape, - tflite_process.detection_queue, tracked_objects_queue, camera_processes[name]['process_fps'], + tflite_process.detection_queue, detection_pipes[name][0], tracked_objects_queue, camera_processes[name]['process_fps'], camera_processes[name]['detection_fps'], camera_processes[name]['read_start'], camera_processes[name]['detection_frame'], stop_event)) camera_process.daemon = True camera_processes[name]['process'] = camera_process + # start the camera_processes for name, camera_process in camera_processes.items(): camera_process['process'].start() print(f"Camera_process started for {name}: {camera_process['process'].pid}") @@ -291,7 +281,7 @@ def main(): object_processor = TrackedObjectProcessor(CONFIG['cameras'], client, MQTT_TOPIC_PREFIX, tracked_objects_queue, event_queue, stop_event) 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, stop_event) camera_watchdog.start() def receiveSignal(signalNumber, frame): @@ -300,11 +290,9 @@ def main(): event_processor.join() object_processor.join() camera_watchdog.join() - for name, camera_process in camera_processes.items(): + for camera_process in camera_processes.values(): camera_process['capture_thread'].join() - rc = camera_watchdog.plasma_process.poll() - if rc == None: - camera_watchdog.plasma_process.terminate() + tflite_process.stop() sys.exit() signal.signal(signal.SIGTERM, receiveSignal) @@ -368,9 +356,6 @@ def main(): 'pid': tflite_process.detect_process.pid } - rc = camera_watchdog.plasma_process.poll() - stats['plasma_store_rc'] = rc - return jsonify(stats) @app.route('//