2023-05-29 12:31:17 +02:00
|
|
|
import io
|
2023-05-05 01:06:07 +02:00
|
|
|
import logging
|
2023-05-29 12:31:17 +02:00
|
|
|
|
2023-05-05 01:06:07 +02:00
|
|
|
import numpy as np
|
|
|
|
import requests
|
2023-05-29 12:31:17 +02:00
|
|
|
from PIL import Image
|
|
|
|
from pydantic import Field
|
|
|
|
from typing_extensions import Literal
|
2023-05-05 01:06:07 +02:00
|
|
|
|
|
|
|
from frigate.detectors.detection_api import DetectionApi
|
|
|
|
from frigate.detectors.detector_config import BaseDetectorConfig
|
|
|
|
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
|
|
DETECTOR_KEY = "deepstack"
|
|
|
|
|
|
|
|
|
|
|
|
class DeepstackDetectorConfig(BaseDetectorConfig):
|
|
|
|
type: Literal[DETECTOR_KEY]
|
|
|
|
api_url: str = Field(
|
|
|
|
default="http://localhost:80/v1/vision/detection", title="DeepStack API URL"
|
|
|
|
)
|
|
|
|
api_timeout: float = Field(default=0.1, title="DeepStack API timeout (in seconds)")
|
|
|
|
api_key: str = Field(default="", title="DeepStack API key (if required)")
|
|
|
|
|
|
|
|
|
|
|
|
class DeepStack(DetectionApi):
|
|
|
|
type_key = DETECTOR_KEY
|
|
|
|
|
|
|
|
def __init__(self, detector_config: DeepstackDetectorConfig):
|
|
|
|
self.api_url = detector_config.api_url
|
|
|
|
self.api_timeout = detector_config.api_timeout
|
|
|
|
self.api_key = detector_config.api_key
|
|
|
|
self.labels = detector_config.model.merged_labelmap
|
|
|
|
|
|
|
|
def get_label_index(self, label_value):
|
|
|
|
if label_value.lower() == "truck":
|
|
|
|
label_value = "car"
|
|
|
|
for index, value in self.labels.items():
|
|
|
|
if value == label_value.lower():
|
|
|
|
return index
|
|
|
|
return -1
|
|
|
|
|
|
|
|
def detect_raw(self, tensor_input):
|
|
|
|
image_data = np.squeeze(tensor_input).astype(np.uint8)
|
|
|
|
image = Image.fromarray(image_data)
|
2023-05-17 14:40:41 +02:00
|
|
|
self.w, self.h = image.size
|
2023-05-05 01:06:07 +02:00
|
|
|
with io.BytesIO() as output:
|
|
|
|
image.save(output, format="JPEG")
|
|
|
|
image_bytes = output.getvalue()
|
|
|
|
data = {"api_key": self.api_key}
|
|
|
|
response = requests.post(
|
2023-05-24 00:32:08 +02:00
|
|
|
self.api_url,
|
|
|
|
data=data,
|
|
|
|
files={"image": image_bytes},
|
|
|
|
timeout=self.api_timeout,
|
2023-05-05 01:06:07 +02:00
|
|
|
)
|
|
|
|
response_json = response.json()
|
|
|
|
detections = np.zeros((20, 6), np.float32)
|
2023-05-15 14:37:34 +02:00
|
|
|
if response_json.get("predictions") is None:
|
|
|
|
logger.debug(f"Error in parsing response json: {response_json}")
|
|
|
|
return detections
|
2023-05-05 01:06:07 +02:00
|
|
|
|
2023-05-15 14:37:34 +02:00
|
|
|
for i, detection in enumerate(response_json.get("predictions")):
|
2023-05-05 01:06:07 +02:00
|
|
|
logger.debug(f"Response: {detection}")
|
|
|
|
if detection["confidence"] < 0.4:
|
2023-05-29 12:31:17 +02:00
|
|
|
logger.debug("Break due to confidence < 0.4")
|
2023-05-05 01:06:07 +02:00
|
|
|
break
|
|
|
|
label = self.get_label_index(detection["label"])
|
|
|
|
if label < 0:
|
2023-05-29 12:31:17 +02:00
|
|
|
logger.debug("Break due to unknown label")
|
2023-05-05 01:06:07 +02:00
|
|
|
break
|
|
|
|
detections[i] = [
|
|
|
|
label,
|
|
|
|
float(detection["confidence"]),
|
|
|
|
detection["y_min"] / self.h,
|
|
|
|
detection["x_min"] / self.w,
|
|
|
|
detection["y_max"] / self.h,
|
|
|
|
detection["x_max"] / self.w,
|
|
|
|
]
|
|
|
|
|
|
|
|
return detections
|