diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 9cc2f38a7ab14ca45a8b0afc47a9d6d1bdef9f6e..dee6d44d4c47aec8dec18603bd41738db512804b 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -28,7 +28,7 @@ image: python:3.9 stages: - - build + - install - test - deploy @@ -51,21 +51,16 @@ cache: #### #### ####################################################################################################################################### -install-virtualenv: - stage: build - script: - - python3 -m venv venv/ - - source venv/bin/activate - - pip install --upgrade pip && pip install pip-tools - - pip install -r ./backend/requirements.txt - - install-npm-packages: image: node:14.6.0 - stage: build + stage: install script: - cd ./frontend - npm ci + artifacts: + paths: + - frontend/node_modules/ + expire_in: 30 mins ####################################################################################################################################### #### #### @@ -77,12 +72,11 @@ lint-back: stage: test allow_failure: true before_script: + - python3 -m venv venv/ - source venv/bin/activate - - pip install pycodestyle script: + - pip install pycodestyle - pycodestyle --config=./backend/setup.cnf ./backend - dependencies: - - install-virtualenv lint-front: diff --git a/backend/.env.template b/backend/.env.template index 8b2bf74be297c91d26ba76eaa54e1b1c534bfd03..56399b0772f6dc796624a789ce13d1b9f8d58e76 100644 --- a/backend/.env.template +++ b/backend/.env.template @@ -6,28 +6,13 @@ MYSQL_ROOT_PASSWORD= DB_HOST=localhost DB_PORT=3306 +MODEL_HOST=localhost +MODEL_PORT=8501 +MODEL_NAME=model + CLIENT_ID= CLIENT_SECRET= API_ROOT=http://localhost:3001/api WEB_ROOT=http://localhost:3000 AUTH_ROOT=https://auth.viarezo.fr - -CAM_NUMBER=1 - -CAM_0_PLACE=local -CAM_0_IP= -CAM_0_USER= -CAM_0_PASSWORD= -CAM_0_STREAM=stream1 -CAM_0_A_FACTOR=30 -CAM_0_B_FACTOR=120 -CAM_0_FRAMEGAP=150 -CAM_0_POINTS_NB=7 -CAM_0_POINT_0=70, 370 -CAM_0_POINT_1=420, 720 -CAM_0_POINT_2=1280, 720 -CAM_0_POINT_3=1280, 250 -CAM_0_POINT_4=930, 215 -CAM_0_POINT_5=450, 550 -CAM_0_POINT_6=130, 350 \ No newline at end of file diff --git a/backend/Dockerfile b/backend/Dockerfile-app similarity index 100% rename from backend/Dockerfile rename to backend/Dockerfile-app diff --git a/backend/Dockerfile-model b/backend/Dockerfile-model new file mode 100644 index 0000000000000000000000000000000000000000..c7fd5a8cd4b8b33b19644b1546326ebde5150ec8 --- /dev/null +++ b/backend/Dockerfile-model @@ -0,0 +1,5 @@ +FROM tensorflow/serving:latest as runtime + +EXPOSE 8501 + +COPY ./model ./models/model/1/ \ No newline at end of file diff --git a/backend/docker-compose.yml b/backend/docker-compose.yml index 72494bd9d8628ccbe572d903be41568ff37a7c80..1586f7782289457a8512593613ec9714aeadde19 100644 --- a/backend/docker-compose.yml +++ b/backend/docker-compose.yml @@ -13,12 +13,14 @@ services: timeout: 1s retries: 3 ports: - - "3306:3306" + - 3306:3306 volumes: - mysql-db:/var/lib/mysql app: - build: . + build: + context: . + dockerfile: Dockerfile-app container_name: "app" depends_on: db: @@ -29,8 +31,21 @@ services: env_file: .env environment: DB_HOST: db + MODEL_HOST: model links: + - model - db + model: + build: + context: . + dockerfile: Dockerfile-model + container_name: "model" + restart: always + ports: + - 8501:8501 + environment: + MODEL_NAME: "model" + volumes: mysql-db: \ No newline at end of file diff --git a/backend/assets/keras_metadata.pb b/backend/model/keras_metadata.pb similarity index 100% rename from backend/assets/keras_metadata.pb rename to backend/model/keras_metadata.pb diff --git a/backend/assets/saved_model.pb b/backend/model/saved_model.pb similarity index 100% rename from backend/assets/saved_model.pb rename to backend/model/saved_model.pb diff --git a/backend/assets/variables/variables.data-00000-of-00001 b/backend/model/variables/variables.data-00000-of-00001 similarity index 100% rename from backend/assets/variables/variables.data-00000-of-00001 rename to backend/model/variables/variables.data-00000-of-00001 diff --git a/backend/assets/variables/variables.index b/backend/model/variables/variables.index similarity index 100% rename from backend/assets/variables/variables.index rename to backend/model/variables/variables.index diff --git a/backend/requirements.txt b/backend/requirements.txt index 035fe7337313c207f6398081f48c0735aa730ecb..8b39d9a9c42f8341d06d24d63702902c92d87029 100644 --- a/backend/requirements.txt +++ b/backend/requirements.txt @@ -1,20 +1,10 @@ -anyio==3.6.1 -asgiref==3.5.2 -click==8.1.3 fastapi==0.78.0 -h11==0.13.0 -idna==2.8 -keras==2.9.0 numpy==1.23.0 opencv-python==4.6.0.66 pydantic==1.9.1 -sniffio==1.2.0 -starlette==0.19.1 -typing-extensions==4.2.0 uvicorn==0.17.6 SQLAlchemy==1.4.19 python-dotenv==0.18.0 PyMySQL==1.0.2 pytz==2022.1 requests==2.25.1 -tensorflow==2.9.1 diff --git a/backend/video_capture.py b/backend/video_capture.py index 9e9e1cca1e72e91826c536070f36082f6aabd567..66eafc8c784c757f3df2b2aaf1fc90101d763376 100644 --- a/backend/video_capture.py +++ b/backend/video_capture.py @@ -1,19 +1,38 @@ import cv2 from datetime import datetime, timedelta -import numpy as np -import keras from utils.preprocessing import fix_singular_shape, norm_by_imagenet +from dotenv import load_dotenv +import numpy as np +import requests import json import time +import os from cameras import restaurants from db import models from db.database import SessionLocal from routers.websocket import manager +load_dotenv() +host = os.getenv('MODEL_HOST') +port = os.getenv('MODEL_PORT') +model = os.getenv('MODEL_NAME') + + +def make_prediction(instances): + url = f"http://{host}:{port}/v1/models/{model}:predict" + data = json.dumps({"signature_name": "serving_default", "instances": instances.tolist()}) + headers = {"content-type": "application/json"} + json_response = requests.post(url, data=data, headers=headers) + try: + predictions = json.loads(json_response.text)['predictions'] + except BaseException: + print("prediction failed") + return predictions + async def handle_cameras(): - model = keras.models.load_model('assets', compile=False) + db = SessionLocal() for restaurant in restaurants: for camera in restaurant["cameras"]: @@ -58,7 +77,7 @@ async def handle_cameras(): [treated_img]))), axis=0) # getting the density map from the model and the number of people - pred_map = np.squeeze(model.predict(input_image, verbose=0)) + pred_map = np.squeeze(make_prediction(input_image)) count_prediction += np.sum(pred_map) for checkout in camera["checkouts"]: # we check whether or not the density in the checkout area is high enough to determine if it is open or not