From edd6818d3cbc8c5805ec2b6cd1f3447a65f7db56 Mon Sep 17 00:00:00 2001 From: Dennis George Date: Sat, 10 Dec 2022 04:54:46 -0600 Subject: [PATCH] fix detector model config defaults --- frigate/app.py | 7 ++++- frigate/config.py | 20 +++++++++++++ frigate/detectors/config.py | 2 +- frigate/object_detection.py | 13 ++++---- frigate/test/test_config.py | 45 +++++++++++++++++++++++++++- frigate/test/test_object_detector.py | 10 ++++--- 6 files changed, 82 insertions(+), 15 deletions(-) diff --git a/frigate/app.py b/frigate/app.py index 88a23774b..0e21359fe 100644 --- a/frigate/app.py +++ b/frigate/app.py @@ -186,7 +186,12 @@ class FrigateApp: self.detection_out_events[name] = mp.Event() try: - size = max([det.model.height * det.model.width * 3 for (name, det) in self.config.detectors.items()]) + size = max( + [ + det.model.height * det.model.width * 3 + for (name, det) in self.config.detectors.items() + ] + ) shm_in = mp.shared_memory.SharedMemory( name=name, create=True, diff --git a/frigate/config.py b/frigate/config.py index 0f307fc14..77b7253eb 100644 --- a/frigate/config.py +++ b/frigate/config.py @@ -975,6 +975,26 @@ class FrigateConfig(FrigateBaseModel): detector_config: DetectorConfig = parse_obj_as(DetectorConfig, detector) if detector_config.model is None: detector_config.model = config.model + else: + model = detector_config.model + schema = ModelConfig.schema()["properties"] + if ( + model.width != schema["width"]["default"] + or model.height != schema["height"]["default"] + or model.labelmap_path is not None + or model.labelmap is not {} + or model.input_tensor != schema["input_tensor"]["default"] + or model.input_pixel_format + != schema["input_pixel_format"]["default"] + ): + logger.warning( + "Customizing more than a detector model path is unsupported." + ) + merged_model = deep_merge( + detector_config.model.dict(exclude_unset=True), + config.model.dict(exclude_unset=True), + ) + detector_config.model = ModelConfig.parse_obj(merged_model) config.detectors[key] = detector_config return config diff --git a/frigate/detectors/config.py b/frigate/detectors/config.py index 3480e8c0c..529f0dcc1 100644 --- a/frigate/detectors/config.py +++ b/frigate/detectors/config.py @@ -60,7 +60,7 @@ class ModelConfig(BaseModel): class BaseDetectorConfig(BaseModel): type: DetectorTypeEnum = Field(default=DetectorTypeEnum.cpu, title="Detector Type") model: ModelConfig = Field( - default_factory=ModelConfig, title="Detector specific model configuration." + default=None, title="Detector specific model configuration." ) class Config: diff --git a/frigate/object_detection.py b/frigate/object_detection.py index bbbc376cf..70eaa1963 100644 --- a/frigate/object_detection.py +++ b/frigate/object_detection.py @@ -38,16 +38,14 @@ class LocalObjectDetector(ObjectDetector): detector_config=None, labels=None, ): - model_config = detector_config.model - self.fps = EventsPerSecond() if labels is None: self.labels = {} else: self.labels = load_labels(labels) - if model_config: - self.input_transform = tensor_transform(model_config.input_tensor) + if detector_config: + self.input_transform = tensor_transform(detector_config.model.input_tensor) else: self.input_transform = None @@ -96,9 +94,7 @@ def run_detector( signal.signal(signal.SIGINT, receiveSignal) frame_manager = SharedMemoryFrameManager() - object_detector = LocalObjectDetector( - detector_config=detector_config - ) + object_detector = LocalObjectDetector(detector_config=detector_config) outputs = {} for name in out_events.keys(): @@ -112,7 +108,8 @@ def run_detector( except queue.Empty: continue input_frame = frame_manager.get( - connection_id, (1, detector_config.model.height, detector_config.model.width, 3) + connection_id, + (1, detector_config.model.height, detector_config.model.width, 3), ) if input_frame is None: diff --git a/frigate/test/test_config.py b/frigate/test/test_config.py index 1b8eba83f..9fa557985 100644 --- a/frigate/test/test_config.py +++ b/frigate/test/test_config.py @@ -7,7 +7,7 @@ from frigate.config import ( FrigateConfig, ) from frigate.detectors import DetectorTypeEnum -from frigate.util import load_config_with_no_duplicates +from frigate.util import deep_merge, load_config_with_no_duplicates class TestConfig(unittest.TestCase): @@ -37,6 +37,49 @@ class TestConfig(unittest.TestCase): runtime_config = frigate_config.runtime_config assert "cpu" in runtime_config.detectors.keys() assert runtime_config.detectors["cpu"].type == DetectorTypeEnum.cpu + assert runtime_config.detectors["cpu"].model.width == 320 + + def test_detector_custom_model_path(self): + config = { + "detectors": { + "cpu": { + "type": "cpu", + "num_threads": 5, + "model": {"path": "/cpu_model.tflite"}, + }, + "edgetpu": { + "type": "edgetpu", + "device": "usb", + "model": {"path": "/edgetpu_model.tflite", "width": 160}, + }, + "openvino": { + "type": "openvino", + "device": "usb", + }, + }, + "model": {"path": "/default.tflite", "width": 512}, + } + + frigate_config = FrigateConfig(**(deep_merge(config, self.minimal))) + runtime_config = frigate_config.runtime_config + + assert "cpu" in runtime_config.detectors.keys() + assert "edgetpu" in runtime_config.detectors.keys() + assert "openvino" in runtime_config.detectors.keys() + + assert runtime_config.detectors["cpu"].type == DetectorTypeEnum.cpu + assert runtime_config.detectors["edgetpu"].type == DetectorTypeEnum.edgetpu + assert runtime_config.detectors["openvino"].type == DetectorTypeEnum.openvino + + assert runtime_config.model.path == "/default.tflite" + assert runtime_config.detectors["cpu"].model.path == "/cpu_model.tflite" + assert runtime_config.detectors["edgetpu"].model.path == "/edgetpu_model.tflite" + assert runtime_config.detectors["openvino"].model.path == "/default.tflite" + + assert runtime_config.model.width == 512 + assert runtime_config.detectors["cpu"].model.width == 512 + assert runtime_config.detectors["edgetpu"].model.width == 160 + assert runtime_config.detectors["openvino"].model.width == 512 def test_invalid_mqtt_config(self): config = { diff --git a/frigate/test/test_object_detector.py b/frigate/test/test_object_detector.py index 4a1e14bae..586ee0979 100644 --- a/frigate/test/test_object_detector.py +++ b/frigate/test/test_object_detector.py @@ -24,7 +24,9 @@ class TestLocalObjectDetector(unittest.TestCase): "frigate.detectors.api_types", {det_type: Mock() for det_type in DetectorTypeEnum}, ): - test_cfg = parse_obj_as(DetectorConfig, {"type": det_type}) + test_cfg = parse_obj_as( + DetectorConfig, {"type": det_type, "model": {}} + ) test_cfg.model.path = "/test/modelpath" test_obj = frigate.object_detection.LocalObjectDetector( detector_config=test_cfg @@ -47,7 +49,7 @@ class TestLocalObjectDetector(unittest.TestCase): TEST_DATA = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] TEST_DETECT_RESULT = np.ndarray([1, 2, 4, 8, 16, 32]) test_obj_detect = frigate.object_detection.LocalObjectDetector( - detector_config=CpuDetectorConfig() + detector_config=CpuDetectorConfig(model=ModelConfig()) ) mock_det_api = mock_cputfl.return_value @@ -70,7 +72,7 @@ class TestLocalObjectDetector(unittest.TestCase): TEST_DATA = np.zeros((1, 32, 32, 3), np.uint8) TEST_DETECT_RESULT = np.ndarray([1, 2, 4, 8, 16, 32]) - test_cfg = CpuDetectorConfig() + test_cfg = CpuDetectorConfig(model=ModelConfig()) test_cfg.model.input_tensor = InputTensorEnum.nchw test_obj_detect = frigate.object_detection.LocalObjectDetector( @@ -119,7 +121,7 @@ class TestLocalObjectDetector(unittest.TestCase): "label-5", ] - test_cfg = CpuDetectorConfig() + test_cfg = CpuDetectorConfig(model=ModelConfig()) test_cfg.model = ModelConfig() test_obj_detect = frigate.object_detection.LocalObjectDetector( detector_config=test_cfg,