From f41c55c1f97e36b4226c12abd8a41bbba75e686d Mon Sep 17 00:00:00 2001 From: quantumrand Date: Mon, 26 Jan 2026 03:32:51 -0800 Subject: [PATCH] Initial attempt at adding Yolo26 support for OpenVino detectors --- frigate/detectors/detector_config.py | 1 + frigate/detectors/plugins/openvino.py | 35 +++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/frigate/detectors/detector_config.py b/frigate/detectors/detector_config.py index aa92f28f4..f460cb119 100644 --- a/frigate/detectors/detector_config.py +++ b/frigate/detectors/detector_config.py @@ -42,6 +42,7 @@ class ModelTypeEnum(str, Enum): yolox = "yolox" yolonas = "yolonas" yologeneric = "yolo-generic" + yolo26 = "yolo26" class ModelConfig(BaseModel): diff --git a/frigate/detectors/plugins/openvino.py b/frigate/detectors/plugins/openvino.py index bda5c8871..3980c7578 100644 --- a/frigate/detectors/plugins/openvino.py +++ b/frigate/detectors/plugins/openvino.py @@ -33,6 +33,7 @@ class OvDetector(DetectionApi): ModelTypeEnum.yolonas, ModelTypeEnum.yologeneric, ModelTypeEnum.yolox, + ModelTypeEnum.yolo26, ] def __init__(self, detector_config: OvDetectorConfig): @@ -82,6 +83,27 @@ class OvDetector(DetectionApi): logger.error(f"SSD model output doesn't match. Found {output_shape}.") self.model_invalid = True + if self.ov_model_type == ModelTypeEnum.yolo26: + model_inputs = self.runner.compiled_model.inputs + model_outputs = self.runner.compiled_model.outputs + + if len(model_inputs) != 1: + logger.error( + f"Yolo26 models must only have 1 input. Found {len(model_inputs)}." + ) + self.model_invalid = True + if len(model_outputs) != 1: + logger.error( + f"Yolo26 models must be exported in flat format and only have 1 output. Found {len(model_outputs)}." + ) + self.model_invalid = True + output_shape = model_outputs[0].partial_shape + if output_shape[-1] != 6: + logger.error( + f"Yolo26 models must be exported in flat format. Model output doesn't match (1, N, 6). Found {output_shape}." + ) + self.model_invalid = True + if self.ov_model_type == ModelTypeEnum.yolonas: model_inputs = self.runner.compiled_model.inputs model_outputs = self.runner.compiled_model.outputs @@ -193,6 +215,19 @@ class OvDetector(DetectionApi): x_max / self.w, ] return detections + elif self.ov_model_type == ModelTypeEnum.yolo26: + # Output shape (batch, predictions, [x_center, y_center, width, height, confidence_score, class_id]) + predictions = outputs[0][0] + + for i, prediction in enumerate(predictions): + if i == 20: + break + (x, y, w, h, confidence, class_id) = prediction + + if class_id < 0: + continue + detections[i] = self.process_yolo(class_id, confidence, [x, y, w, h]) + return detections elif self.ov_model_type == ModelTypeEnum.yologeneric: return post_process_yolo(outputs, self.w, self.h) elif self.ov_model_type == ModelTypeEnum.yolox: