Skip to content

Commit

Permalink
Merge pull request #8 from 5sControl/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
eugenos-programos authored Jul 19, 2023
2 parents 82f2d7a + 299d99b commit 5da8d13
Show file tree
Hide file tree
Showing 23 changed files with 259 additions and 211 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ __pycache__
.vscode/
build/
cmake-build-debug/
idle_models/weights/
idle_model/weights/
10 changes: 9 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,9 @@
# algorithms-python
# algorithms-python

```bash
docker build ./idle_models -t 5scontrol/idle_python_server:v-.-.-
docker build . -t 5scontrol/idle_python:v-.-.-

docker run --network host --rm 5scontrol/idle_python_server:v-.-.-
docker run --network host --rm 5scontrol/idle_python:v-.-.-
```
2 changes: 2 additions & 0 deletions confs/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from .load_configs import load_configs
configs = load_configs()
3 changes: 0 additions & 3 deletions confs/configs.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
{
"classes": [
77
],
"wait_time": 10,
"threshold": 100
}
13 changes: 5 additions & 8 deletions confs/load_configs.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
import json
import os


with open("confs/configs.json", "r") as conf:
configs = json.load(conf)
CONF_THRES = configs.get("conf_thres")
IOU_THRES = configs.get("iou_thres")
MODEL_PATH = configs.get("model_path")
CLASSES = configs.get("classes")
WAIT_TIME = configs.get("wait_time")
THRESHOLD = configs.get("threshold")
def load_configs() -> dict:
with open("confs/configs.json", "r") as conf:
configs = json.load(conf)
return configs
47 changes: 47 additions & 0 deletions connection/IdleReporter.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import os
import time
import logging
import requests
import datetime
import uuid
import cv2
import numpy as np


class IdleReporter:
def __init__(self, images_folder: str, server_url: str, wait_time: int, logger: logging.Logger) -> None:
self.images_folder = images_folder
self.server_url = server_url
self.wait_time = wait_time
self.logger = logger
os.makedirs(self.images_folder, exist_ok=True)

def _save_image(self, image: np.array) -> str:
save_photo_url = f'{self.images_folder}/' + str(uuid.uuid4()) + '.jpg'
cv2.imwrite(save_photo_url, image)
return save_photo_url

def create_report(self, image: np.array, start_tracking_time: datetime.time) -> dict:
time.sleep(self.wait_time)
stop_tracking_time = str(datetime.datetime.now())
saved_image_name = self._save_image(image)
report_for_send = {
'camera': self.images_folder.split('/')[1],
'algorithm': 'idle_control',
'start_tracking': start_tracking_time,
'stop_tracking': stop_tracking_time,
'photos': [{'image': saved_image_name, 'date': start_tracking_time}],
'violation_found': True,
}
return report_for_send

def send_report(self, report: dict) -> None:
try:
self.logger.info(str(report))
requests.post(
url=f'{self.server_url}:80/api/reports/report-with-photos/', json=report
)
except Exception as exc:
self.logger.error(f"Cannot send report. Following error raised: {str(exc)}")


29 changes: 29 additions & 0 deletions connection/ImageHTTPExtractor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import httplib2
import logging
import datetime
import numpy as np
import cv2
from typing import Tuple, Union


class ImageHTTPExtractor:
def __init__(self, server_url: str, logger: logging.Logger, **credentials) -> None:
self.http_connection = httplib2.Http(".cache")
self.http_connection.add_credentials(credentials.get("username"), credentials.get("password"))
self.logger = logger
self.server_url = server_url

def get_snapshot(self) -> Tuple[Union[cv2.Mat, None], Union[datetime.time, None]]:
try:
curr_time = datetime.datetime.now()
response, content = self.http_connection.request(
self.server_url,
"GET",
body="foobar"
)
nparr = np.frombuffer(content, np.uint8)
img = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
return img, curr_time
except Exception as exc:
self.logger.error(f"Cannot retrieve image. Following error raised - {exc}")
return None, None
50 changes: 50 additions & 0 deletions connection/ModelPredictionsReceiver.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import requests
import numpy as np
from logging import Logger
from PIL import Image
import io


PORT = 5001


class ModelPredictionsReceiver:
def __init__(self, server_url: str, logger: Logger) -> None:
self.server_url = server_url
self.logger = logger

@staticmethod
def _convert_image2bytes(image: np.array, format='PNG') -> io.BytesIO:
pil_image = Image.fromarray(image)
img_byte_arr = io.BytesIO()
pil_image.save(img_byte_arr, format=format)
img_byte_arr.seek(0)
return img_byte_arr

def _predict(self, img: np.array) -> np.array:
try:
response = requests.post(
f"{self.server_url}:{PORT}/predict",
files={
"image": ("image", self._convert_image2bytes(img), "image/png")
}
)
response.raise_for_status()
return np.array(response.json().get("coordinates"))
except Exception as exc:
self.logger.critical("Cannot send request to model server. Error - {}".format(exc))
return np.array([])

def predict(self, img: np.array) -> np.array:
imgs = [
img[:img.shape[0] // 2, :, :],
img[img.shape[0] // 2:, :, :]
]
preds = [self._predict(imgs[0]), self._predict(imgs[1])]
if len(preds[1]):
preds[1][:, 1] += img.shape[0] // 2
preds[1][:, 3] += img.shape[0] // 2
result = np.append(*preds)
if len(result.shape) == 1:
result = np.expand_dims(result, 0)
return result
3 changes: 3 additions & 0 deletions connection/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from .IdleReporter import IdleReporter
from .ImageHTTPExtractor import ImageHTTPExtractor
from .ModelPredictionsReceiver import ModelPredictionsReceiver
95 changes: 0 additions & 95 deletions functional.py

This file was deleted.

File renamed without changes.
24 changes: 24 additions & 0 deletions idle_model/IdleObjectDetectionModel.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import torch
import numpy as np
import torch
from ultralytics import YOLO


class IdleObjectDetectionModel:
def __init__(self, path: str, conf_thresh, iou_thresh, classes) -> None:
self.model = YOLO(path)
self.conf_thresh = conf_thresh
self.iou_thresh = iou_thresh
self.classes = classes

@torch.no_grad()
def __call__(self, img: np.array) -> np.array:
output = self.model(
source=img,
conf=self.conf_thresh,
iou=self.iou_thresh,
max_det=600,
classes=self.classes,
verbose=False
)[0].boxes
return output.xyxy
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
67
],
"iou_thres": 0.5,
"conf_thres": 0.65,
"model_path": "./weights",
"conf_thres": 0.8,
"model_path": "weights/yolov8l.pt",
"port": 5001
}
10 changes: 10 additions & 0 deletions idle_model/configs/load_configs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import json


with open("configs/confs.json", "r") as conf:
configs = json.load(conf)
CONF_THRES = configs.get("conf_thres")
IOU_THRES = configs.get("iou_thres")
MODEL_PATH = configs.get("model_path")
CLASSES = configs.get("classes")
PORT = configs.get("port")
3 changes: 1 addition & 2 deletions idle_models/requirements.txt → idle_model/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,4 @@ PyYAML==6.0
requests==2.27.1
Flask==2.2.2
colorlog==4.8.0
transformers==4.28.1
timm==0.6.13
ultralytics==8.0.136
26 changes: 0 additions & 26 deletions idle_models/IdleObjectDetectionModel.py

This file was deleted.

10 changes: 0 additions & 10 deletions idle_models/configs/load_configs.py

This file was deleted.

Loading

0 comments on commit 5da8d13

Please sign in to comment.