mirror of
https://github.com/blakeblackshear/frigate.git
synced 2025-12-06 21:44:13 +03:00
Compare commits
4 Commits
6e288839be
...
97a5f3092d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
97a5f3092d | ||
|
|
756573313e | ||
|
|
f5f84a3c53 | ||
|
|
6ee36d6ffc |
@ -161,12 +161,6 @@ A Tensorflow Lite is provided in the container at `/openvino-model/ssdlite_mobil
|
|||||||
|
|
||||||
[YOLOv9](https://github.com/dbro/frigate-detector-edgetpu-yolo9/releases/download/v1.0/yolov9-s-relu6-best_320_int8_edgetpu.tflite) models that are compiled for Tensorflow Lite and properly quantized are supported, but not included by default. To provide your own model, bind mount the file into the container and provide the path with `model.path`. Note that the model may require a custom label file (eg. [use this 17 label file](https://raw.githubusercontent.com/dbro/frigate-detector-edgetpu-yolo9/refs/heads/main/labels-coco17.txt) for the model linked above.)
|
[YOLOv9](https://github.com/dbro/frigate-detector-edgetpu-yolo9/releases/download/v1.0/yolov9-s-relu6-best_320_int8_edgetpu.tflite) models that are compiled for Tensorflow Lite and properly quantized are supported, but not included by default. To provide your own model, bind mount the file into the container and provide the path with `model.path`. Note that the model may require a custom label file (eg. [use this 17 label file](https://raw.githubusercontent.com/dbro/frigate-detector-edgetpu-yolo9/refs/heads/main/labels-coco17.txt) for the model linked above.)
|
||||||
|
|
||||||
:::tip
|
|
||||||
|
|
||||||
The YOLO detector has been designed to support YOLOv9 models, and may support other YOLO model architectures as well.
|
|
||||||
|
|
||||||
:::
|
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary>YOLOv9 Setup & Config</summary>
|
<summary>YOLOv9 Setup & Config</summary>
|
||||||
|
|
||||||
|
|||||||
@ -9,7 +9,6 @@ from typing_extensions import Literal
|
|||||||
|
|
||||||
from frigate.detectors.detection_api import DetectionApi
|
from frigate.detectors.detection_api import DetectionApi
|
||||||
from frigate.detectors.detector_config import BaseDetectorConfig, ModelTypeEnum
|
from frigate.detectors.detector_config import BaseDetectorConfig, ModelTypeEnum
|
||||||
from frigate.util.model import post_process_yolo
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from tflite_runtime.interpreter import Interpreter, load_delegate
|
from tflite_runtime.interpreter import Interpreter, load_delegate
|
||||||
@ -81,7 +80,7 @@ class EdgeTpuTfl(DetectionApi):
|
|||||||
if self.model_type == ModelTypeEnum.yologeneric:
|
if self.model_type == ModelTypeEnum.yologeneric:
|
||||||
logger.debug("Using YOLO preprocessing/postprocessing")
|
logger.debug("Using YOLO preprocessing/postprocessing")
|
||||||
|
|
||||||
if len(self.tensor_output_details) not in [2,3]:
|
if len(self.tensor_output_details) not in [2, 3]:
|
||||||
logger.error(
|
logger.error(
|
||||||
f"Invalid count of output tensors in YOLO model. Found {len(self.tensor_output_details)}, expecting 2 or 3."
|
f"Invalid count of output tensors in YOLO model. Found {len(self.tensor_output_details)}, expecting 2 or 3."
|
||||||
)
|
)
|
||||||
@ -114,9 +113,7 @@ class EdgeTpuTfl(DetectionApi):
|
|||||||
# to differentiate from (not used) max score tensor
|
# to differentiate from (not used) max score tensor
|
||||||
output_classes_index = i
|
output_classes_index = i
|
||||||
if output_boxes_index is None or output_classes_index is None:
|
if output_boxes_index is None or output_classes_index is None:
|
||||||
logger.warning(
|
logger.warning("Unrecognized model output, unexpected tensor shapes.")
|
||||||
"Unrecognized model output, unexpected tensor shapes."
|
|
||||||
)
|
|
||||||
output_classes_index = (
|
output_classes_index = (
|
||||||
0
|
0
|
||||||
if (output_boxes_index is None or output_classes_index == 1)
|
if (output_boxes_index is None or output_classes_index == 1)
|
||||||
@ -125,19 +122,14 @@ class EdgeTpuTfl(DetectionApi):
|
|||||||
output_boxes_index = 1 if (output_boxes_index == 0) else 0
|
output_boxes_index = 1 if (output_boxes_index == 0) else 0
|
||||||
|
|
||||||
scores_details = self.tensor_output_details[output_classes_index]
|
scores_details = self.tensor_output_details[output_classes_index]
|
||||||
classes_count = scores_details["shape"][2]
|
|
||||||
self.scores_tensor_index = scores_details["index"]
|
self.scores_tensor_index = scores_details["index"]
|
||||||
self.scores_scale, self.scores_zero_point = scores_details[
|
self.scores_scale, self.scores_zero_point = scores_details["quantization"]
|
||||||
"quantization"
|
|
||||||
]
|
|
||||||
# calculate the quantized version of the min_score
|
# calculate the quantized version of the min_score
|
||||||
self.min_score_quantized = int(
|
self.min_score_quantized = int(
|
||||||
(self.min_logit_value / self.scores_scale) + self.scores_zero_point
|
(self.min_logit_value / self.scores_scale) + self.scores_zero_point
|
||||||
)
|
)
|
||||||
self.logit_shift_to_positive_values = (
|
self.logit_shift_to_positive_values = (
|
||||||
max(
|
max(0, math.ceil((128 + self.scores_zero_point) * self.scores_scale))
|
||||||
0, math.ceil((128 + self.scores_zero_point) * self.scores_scale)
|
|
||||||
)
|
|
||||||
+ 1
|
+ 1
|
||||||
) # round up
|
) # round up
|
||||||
|
|
||||||
@ -145,11 +137,7 @@ class EdgeTpuTfl(DetectionApi):
|
|||||||
self.boxes_tensor_index = boxes_details["index"]
|
self.boxes_tensor_index = boxes_details["index"]
|
||||||
self.boxes_scale, self.boxes_zero_point = boxes_details["quantization"]
|
self.boxes_scale, self.boxes_zero_point = boxes_details["quantization"]
|
||||||
|
|
||||||
else:
|
elif self.model_type == ModelTypeEnum.ssd:
|
||||||
if self.model_type not in [ModelTypeEnum.ssd, None]:
|
|
||||||
logger.warning(
|
|
||||||
f"Unsupported model_type '{self.model_type}' for EdgeTPU detector, falling back to SSD"
|
|
||||||
)
|
|
||||||
logger.debug("Using SSD preprocessing/postprocessing")
|
logger.debug("Using SSD preprocessing/postprocessing")
|
||||||
|
|
||||||
# SSD model indices (4 outputs: boxes, class_ids, scores, count)
|
# SSD model indices (4 outputs: boxes, class_ids, scores, count)
|
||||||
@ -162,6 +150,11 @@ class EdgeTpuTfl(DetectionApi):
|
|||||||
self.output_class_ids_index = None
|
self.output_class_ids_index = None
|
||||||
self.output_class_scores_index = None
|
self.output_class_scores_index = None
|
||||||
|
|
||||||
|
else:
|
||||||
|
raise Exception(
|
||||||
|
f"{self.model_type} is currently not supported for edgetpu. See the docs for more info on supported models."
|
||||||
|
)
|
||||||
|
|
||||||
def _generate_anchors_and_strides(self):
|
def _generate_anchors_and_strides(self):
|
||||||
# for decoding the bounding box DFL information into xy coordinates
|
# for decoding the bounding box DFL information into xy coordinates
|
||||||
all_anchors = []
|
all_anchors = []
|
||||||
@ -244,9 +237,7 @@ class EdgeTpuTfl(DetectionApi):
|
|||||||
scores_output_quantized = self.interpreter.get_tensor(
|
scores_output_quantized = self.interpreter.get_tensor(
|
||||||
self.scores_tensor_index
|
self.scores_tensor_index
|
||||||
)[0] # (2100, NC)
|
)[0] # (2100, NC)
|
||||||
max_scores_quantized = np.max(
|
max_scores_quantized = np.max(scores_output_quantized, axis=1) # (2100,)
|
||||||
scores_output_quantized, axis=1
|
|
||||||
) # (2100,)
|
|
||||||
mask = max_scores_quantized >= self.min_score_quantized # (2100,)
|
mask = max_scores_quantized >= self.min_score_quantized # (2100,)
|
||||||
|
|
||||||
if not np.any(mask):
|
if not np.any(mask):
|
||||||
@ -276,9 +267,7 @@ class EdgeTpuTfl(DetectionApi):
|
|||||||
# Softmax over the 16 bins
|
# Softmax over the 16 bins
|
||||||
dfl_max = np.max(dfl_distributions, axis=2, keepdims=True)
|
dfl_max = np.max(dfl_distributions, axis=2, keepdims=True)
|
||||||
dfl_exp = np.exp(dfl_distributions - dfl_max)
|
dfl_exp = np.exp(dfl_distributions - dfl_max)
|
||||||
dfl_probs = dfl_exp / np.sum(
|
dfl_probs = dfl_exp / np.sum(dfl_exp, axis=2, keepdims=True) # (N, 4, 16)
|
||||||
dfl_exp, axis=2, keepdims=True
|
|
||||||
) # (N, 4, 16)
|
|
||||||
|
|
||||||
# Weighted sum: (N, 4, 16) * (16,) -> (N, 4)
|
# Weighted sum: (N, 4, 16) * (16,) -> (N, 4)
|
||||||
distances = np.einsum("pcr,r->pc", dfl_probs, self.project)
|
distances = np.einsum("pcr,r->pc", dfl_probs, self.project)
|
||||||
@ -334,8 +323,7 @@ class EdgeTpuTfl(DetectionApi):
|
|||||||
detections[:num_detections, 5] = final_boxes[:, 2] / self.model_width
|
detections[:num_detections, 5] = final_boxes[:, 2] / self.model_width
|
||||||
return detections
|
return detections
|
||||||
|
|
||||||
else:
|
elif self.model_type == ModelTypeEnum.ssd:
|
||||||
# Default SSD model
|
|
||||||
self.determine_indexes_for_non_yolo_models()
|
self.determine_indexes_for_non_yolo_models()
|
||||||
boxes = self.interpreter.tensor(self.tensor_output_details[0]["index"])()[0]
|
boxes = self.interpreter.tensor(self.tensor_output_details[0]["index"])()[0]
|
||||||
class_ids = self.interpreter.tensor(
|
class_ids = self.interpreter.tensor(
|
||||||
@ -366,3 +354,8 @@ class EdgeTpuTfl(DetectionApi):
|
|||||||
]
|
]
|
||||||
|
|
||||||
return detections
|
return detections
|
||||||
|
|
||||||
|
else:
|
||||||
|
raise Exception(
|
||||||
|
f"{self.model_type} is currently not supported for edgetpu. See the docs for more info on supported models."
|
||||||
|
)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user