Skip to content

Commit

Permalink
Draft #11
Browse files Browse the repository at this point in the history
  • Loading branch information
heming-h committed May 27, 2024
1 parent 378ea0f commit e54657e
Show file tree
Hide file tree
Showing 13 changed files with 284 additions and 166 deletions.
45 changes: 45 additions & 0 deletions .github/workflows/deploy_server.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
name: Test, build and deploy server

on:
push:
branches:
- main

jobs:
build-and-deploy:
name: Build, test and deploy to GitHub Container registry
runs-on: ubuntu-latest
if: github.event.pull_request.draft == false

steps:
- uses: actions/checkout@v3

- name: Set up Python 3.11
uses: actions/setup-python@v4
with:
python-version: 3.11
architecture: x64

- name: Install dependencies
run: |-
pipx install poetry==1.7.1
pipx install nox==2022.11.21
pipx inject nox nox-poetry
- name: Build image and test with nox
run: |-
nox
env:
JWT_SECRET: ${{ secrets.JWT_SECRET }}
ADMIN_USERNAME: ${{ secrets.ADMIN_USERNAME }}
ADMIN_PASSWORD: ${{ secrets.ADMIN_PASSWORD }}

- name: Log in to registry
run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin

- name: Tag and publish docker image to Github Container registry
env:
GITHUB_TOKEN: ${{ github.token }}
run: |-
docker tag ghcr.io/langrenn-sprint/vision-ai-service:test ghcr.io/langrenn-sprint/vision-ai-service:latest
docker rmi ghcr.io/langrenn-sprint/vision-ai-service:test
docker push ghcr.io/langrenn-sprint/vision-ai-service:latest
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -139,3 +139,4 @@ dmypy.json
*.mp4
*.pt
.DS_Store
Finish_line_config.jpg
6 changes: 4 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ RUN poetry config virtualenvs.create false \

ADD vision-ai-service /app/vision-ai-service

EXPOSE 8080
RUN apt-get update && apt-get install -y libgl1-mesa-glx

CMD gunicorn "photo_service_gui:create_app" --config=vision-ai-service/gunicorn_config.py --worker-class aiohttp.GunicornWebWorker
# RUN pip install gunicorn
# CMD gunicorn "vision-ai-service:create_app"
CMD python3 vision-ai-service/app.py
5 changes: 2 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,8 @@ Usage: python3 vision-ai-service/app.py

### Prepare .env filer (dummy parameter values supplied)
LOGGING_LEVEL=INFO
PHOTOS_FILE_PATH=/Users/t520834/github/photo-service-gui/docs/photos
VIDEO_URL=http://localhost:8080/video
DETECTION_BOX_MINIMUM_SIZE=0.08
PHOTOS_FILE_PATH=vision-ai-service/files
VIDEO_URL=https://harnaes.no/maalfoto/2023SkiMaal.mp4
GLOBAL_SETTINGS_FILE=vision-ai-service/config/global_settings.json
VIDEO_STATUS_FILE=vision-ai-service/config/video_status.json

Expand Down
16 changes: 14 additions & 2 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,19 @@ services:
environment:
- HOST_PORT=8080
- LOGGING_LEVEL=${LOGGING_LEVEL}
- GLOBAL_SETTINGS_FILE=vision-ai-service/config/global_settings.json
- VIDEO_STATUS_FILE=vision-ai-service/config/video_status.json
- PHOTOS_FILE_PATH=tests/files
volumes:
- type: bind
source: .
target: /app
source: ${GLOBAL_SETTINGS_FILE}
target: /app/${GLOBAL_SETTINGS_FILE}
- type: bind
source: ${VIDEO_STATUS_FILE}
target: /app/${VIDEO_STATUS_FILE}
- type: bind
source: ${PHOTOS_FILE_PATH}
target: /app/${PHOTOS_FILE_PATH}
- type: bind
source: error.log
target: /app/error.log
284 changes: 171 additions & 113 deletions poetry.lock

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ piexif = "^1.1.3"
pillow = "^10.1.0"
ultralytics = "^8.2"
click = "^8.1.7"
lapx = "^0.5.9"


[tool.poetry.group.dev.dependencies]
Expand Down
22 changes: 11 additions & 11 deletions vision-ai-service/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,21 +41,21 @@ def main() -> None:
while True:
try:
click.echo("Vision AI is idle...")
analytics_running = EventsAdapter().get_global_setting(
analytics_running = EventsAdapter().get_global_setting_bool(
"VIDEO_ANALYTICS_RUNNING"
)
analytics_start = EventsAdapter().get_global_setting(
analytics_start = EventsAdapter().get_global_setting_bool(
"VIDEO_ANALYTICS_START"
)
stop_tracking = EventsAdapter().get_global_setting("VIDEO_ANALYTICS_STOP")
trigger_line = EventsAdapter().get_global_setting("DRAW_TRIGGER_LINE")
stop_tracking = EventsAdapter().get_global_setting_bool("VIDEO_ANALYTICS_STOP")
draw_trigger_line = EventsAdapter().get_global_setting_bool("DRAW_TRIGGER_LINE")

if stop_tracking == "true":
if stop_tracking:
EventsAdapter().update_global_setting("VIDEO_ANALYTICS_STOP", "false")
elif (analytics_running == "false") and (analytics_start == "true"):
elif (not analytics_running) and (analytics_start):
click.echo("Vision AI video detection is started...")
EventsAdapter().add_video_service_message("Starter AI video detection.")
EventsAdapter().update_global_setting("VIDEO_ANALYTICS_START", "false")
EventsAdapter().update_global_setting("VIDEO_ANALYTICS_START", "False")
result = VisionAIService2().detect_crossings_with_ultraltyics(
photos_file_path
)
Expand All @@ -64,17 +64,17 @@ def main() -> None:
"Avsluttet AI video detection."
)
click.echo(f"Video detection complete - {result}")
elif (analytics_running == "false") and (trigger_line == "true"):
elif (not analytics_running) and (draw_trigger_line):
click.echo("Vision trigger line detection is started...")
EventsAdapter().update_global_setting("DRAW_TRIGGER_LINE", "false")
EventsAdapter().update_global_setting("DRAW_TRIGGER_LINE", "False")
result = VisionAIService2().draw_trigger_line_with_ultraltyics(
photos_file_path
)
click.echo(f"Trigger line complete - {result}")
elif analytics_running == "true":
elif analytics_running:
# invalid scenario - reset
EventsAdapter().update_global_setting(
"VIDEO_ANALYTICS_RUNNING", "false"
"VIDEO_ANALYTICS_RUNNING", "False"
)
time.sleep(5)

Expand Down
9 changes: 5 additions & 4 deletions vision-ai-service/config/global_settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,11 @@
"TRIGGER_LINE_XYXYN": "0:0.75:1:0.75",
"VIDEO_URL": "20240113_105758_KJ.mp4",
"CAMERA_LOCATION": "Finish",
"VIDEO_ANALYTICS_START": "true",
"VIDEO_ANALYTICS_RUNNING": "false",
"VIDEO_ANALYTICS_STOP": "false",
"DRAW_TRIGGER_LINE": "false",
"VIDEO_ANALYTICS_START": "False",
"VIDEO_ANALYTICS_RUNNING": "true",
"VIDEO_ANALYTICS_STOP": "False",
"DRAW_TRIGGER_LINE": "False",
"SHOW_VIDEO": "False",
"DETECTION_BOX_MINIMUM_SIZE": "0.08",
"DETECTION_BOX_MAXIMUM_SIZE": "0.9"
}
11 changes: 0 additions & 11 deletions vision-ai-service/config/ski_tracker.yaml

This file was deleted.

15 changes: 7 additions & 8 deletions vision-ai-service/config/video_status.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
{
"20240204 20:32:36": "New trigger line photo",
"20240204 20:32:35": "Updated config: DRAW_TRIGGER_LINE to false",
"20240204 20:32:03": "Updated config: VIDEO_ANALYTICS_START to false",
"20240204 20:31:58": "Updated config: VIDEO_ANALYTICS_START to false",
"20240204 20:31:53": "New trigger line photo",
"20240204 19:55:48": "Updated config: VIDEO_ANALYTICS_RUNNING to true"
}
[
"15:35:52 Trigger line photo created",
"15:35:49 Starter AI video detection.",
"15:35:29 Vision AI is ready.",
"15:28:56 Trigger line photo created",
"15:28:21 Starter AI video detection.",

20 changes: 15 additions & 5 deletions vision-ai-service/events_adapter.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ def get_env(self, param_name: str) -> str:
logging.error(err_info)
raise FileNotFoundError(err_info) from e
except Exception as e:
err_info = f"Erorr loading env {param_name}. {e}"
err_info = f"Error loading env {param_name}. {e}"
logging.error(err_info)
raise Exception(err_info) from e
return env_param
Expand All @@ -60,6 +60,15 @@ def get_global_setting(self, param_name: str) -> str:
raise Exception from e
return global_setting

def get_global_setting_bool(self, param_name: str) -> bool:
"""Get global setting boolean from global_settings.json file."""
string_value = self.get_global_setting(param_name)
boolean_value = False
if string_value in ["True", "true", "1"]:
boolean_value = True

return boolean_value

def get_video_service_status_messages(self) -> list:
"""Get video service status."""
video_status = []
Expand All @@ -68,7 +77,7 @@ def get_video_service_status_messages(self) -> list:
with open(config_file, "r") as json_file:
video_status = json.load(json_file)
except Exception as e:
err_info = f"Erorr loading video status. File path {config_file} - {e}"
err_info = f"Error getting video status message. File path {config_file} - {e}"
logging.error(err_info)
raise Exception(err_info) from e
return video_status
Expand Down Expand Up @@ -96,16 +105,17 @@ def add_video_service_message(self, message: str) -> None:
json.dump(video_status, json_file)

except Exception as e:
err_info = f"Erorr updating video status. File path {config_file} - {e}"
err_info = f"Error adding video service message. File path {config_file} - {e}"
logging.error(err_info)
raise Exception(err_info) from e

def update_global_setting(self, param_name: str, new_value: str) -> None:
"""Update global_settings file."""
config_file = self.get_env("VIDEO_STATUS_FILE")
config_file = self.get_env("GLOBAL_SETTINGS_FILE")
try:
# Open the global settings file in read-only mode.
with open(config_file, "r") as json_file:
settings = []
settings = json.load(json_file)

# Update the value of the global setting in the dictionary.
Expand All @@ -116,7 +126,7 @@ def update_global_setting(self, param_name: str, new_value: str) -> None:
json.dump(settings, json_file)

except Exception as e:
err_info = f"Erorr updating global setting {param_name}. File path {config_file} - {e}"
err_info = f"Error updating global setting {param_name}. File path {config_file} - {e}"
logging.error(err_info)
raise Exception(err_info) from e

Expand Down
15 changes: 8 additions & 7 deletions vision-ai-service/vision_ai_service_v2.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,17 +33,18 @@ def detect_crossings_with_ultraltyics(
crossings = {}
crossings = VisionAIService2().reset_line_crossings(crossings)
firstDetection = True
video_url = EventsAdapter().get_global_setting("VIDEO_URL")
camera_location = EventsAdapter().get_global_setting("CAMERA_LOCATION")
show_video = EventsAdapter().get_global_setting_bool("SHOW_VIDEO")

informasjon = ""

# Load an official or custom model
model = YOLO("yolov8n.pt") # Load an official Detect model

# Perform tracking with the model
results = model.track(source=video_url, show=True, stream=True, persist=True)
results = model.track(source=photos_file_path, show=show_video, stream=True, persist=True)
# open new stream to capture higher quality image
cap = cv2.VideoCapture(video_url)
cap = cv2.VideoCapture(photos_file_path)
EventsAdapter().update_global_setting("VIDEO_ANALYTICS_RUNNING", "true")

for result in results:
Expand Down Expand Up @@ -335,11 +336,11 @@ def save_image(

def check_stop_tracking(self) -> bool:
"""Check status flags and determine if tracking should continue."""
stop_tracking = EventsAdapter().get_global_setting("VIDEO_ANALYTICS_STOP")
if stop_tracking == "true":
stop_tracking = EventsAdapter().get_global_setting_bool("VIDEO_ANALYTICS_STOP")
if stop_tracking:
EventsAdapter().add_video_service_message("Video analytics stopped.")
EventsAdapter().update_global_setting("VIDEO_ANALYTICS_RUNNING", "false")
EventsAdapter().update_global_setting("VIDEO_ANALYTICS_STOP", "false")
EventsAdapter().update_global_setting("VIDEO_ANALYTICS_RUNNING", "False")
EventsAdapter().update_global_setting("VIDEO_ANALYTICS_STOP", "False")
return True
return False

Expand Down

0 comments on commit e54657e

Please sign in to comment.