Skip to content

Commit e7053a2

Browse files
authored
Merge pull request #1272 from roflcoopter/feature/darknet-reload
feat(darknet): support config reload
2 parents 7d029a4 + 611d5e2 commit e7053a2

File tree

1 file changed

+34
-13
lines changed

1 file changed

+34
-13
lines changed

viseron/components/darknet/__init__.py

Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
"""Darknet object detection."""
2+
23
from __future__ import annotations
34

45
import configparser
@@ -8,13 +9,11 @@
89
import pwd
910
from abc import ABC, abstractmethod
1011
from queue import Empty, Queue
11-
from typing import Any
12+
from typing import TYPE_CHECKING, Any
1213

1314
import cv2
14-
import numpy as np
1515
import voluptuous as vol
1616

17-
from viseron import Viseron
1817
from viseron.const import ENV_CUDA_SUPPORTED, ENV_OPENCL_SUPPORTED
1918
from viseron.domains import OptionalDomain, RequireDomain, setup_domain
2019
from viseron.domains.motion_detector.const import DOMAIN as MOTION_DETECTOR_DOMAIN
@@ -64,6 +63,11 @@
6463
DNN_TARGETS,
6564
)
6665

66+
if TYPE_CHECKING:
67+
import numpy as np
68+
69+
from viseron import Viseron
70+
6771
LOGGER = logging.getLogger(__name__)
6872

6973
CONFIG_SCHEMA = vol.Schema(
@@ -140,7 +144,7 @@ def setup_domains(vis: Viseron, config: dict[str, Any]) -> None:
140144
"""Set up darknet domains."""
141145
config = config[COMPONENT]
142146

143-
for camera_identifier in config[CONFIG_OBJECT_DETECTOR][CONFIG_CAMERAS].keys():
147+
for camera_identifier in config[CONFIG_OBJECT_DETECTOR][CONFIG_CAMERAS]:
144148
setup_domain(
145149
vis,
146150
COMPONENT,
@@ -162,6 +166,13 @@ def setup_domains(vis: Viseron, config: dict[str, Any]) -> None:
162166
)
163167

164168

169+
def unload(vis: Viseron) -> None:
170+
"""Unload the darknet component."""
171+
if COMPONENT in vis.data:
172+
vis.data[COMPONENT].stop()
173+
del vis.data[COMPONENT]
174+
175+
165176
class LoadDarknetError(ViseronError):
166177
"""Raised when failing to load Darknet network."""
167178

@@ -210,22 +221,26 @@ def model_height(self) -> int:
210221
return self._model_height
211222

212223
@property
213-
def model_res(self):
224+
def model_res(self) -> tuple[int, int]:
214225
"""Return trained model resolution."""
215226
return self.model_width, self.model_height
216227

217228
@abstractmethod
218-
def preprocess(self, frame):
229+
def preprocess(self, frame: np.ndarray) -> np.ndarray | bytes:
219230
"""Pre process frame before detection."""
220231

221232
@abstractmethod
222233
def detect(self, frame, camera_identifier, result_queue, min_confidence):
223234
"""Perform detection."""
224235

225236
@abstractmethod
226-
def post_process(self, detections, camera_resolution):
237+
def post_process(self, detections, camera_resolution) -> list[DetectedObject]:
227238
"""Post process detections."""
228239

240+
@abstractmethod
241+
def stop(self) -> None:
242+
"""Stop Darknet."""
243+
229244

230245
class DarknetDNNError(ViseronError):
231246
"""Raised when failing to load Darknet in subprocess."""
@@ -278,7 +293,7 @@ def spawn_subprocess(self) -> RestartablePopen:
278293
stderr=self._log_pipe,
279294
)
280295

281-
def preprocess(self, frame) -> np.ndarray:
296+
def preprocess(self, frame: np.ndarray) -> np.ndarray:
282297
"""Pre process frame before detection."""
283298
return cv2.resize(
284299
frame,
@@ -315,12 +330,10 @@ def work_output(self, item) -> None:
315330
return
316331
pop_if_full(self._result_queues[item["camera_identifier"]], item)
317332

318-
def post_process(self, detections, camera_resolution):
333+
def post_process(self, detections, camera_resolution) -> list[DetectedObject]:
319334
"""Post process detections."""
320335
_detections = []
321-
for (label, confidence, box) in zip(
322-
detections[0], detections[1], detections[2]
323-
):
336+
for label, confidence, box in zip(detections[0], detections[1], detections[2]):
324337
_detections.append(
325338
DetectedObject.from_absolute(
326339
self.labels[int(label)],
@@ -354,6 +367,10 @@ def dnn_preferable_target(self) -> int:
354367
return DNN_TARGETS[DNN_OPENCL]
355368
return DNN_TARGETS[DNN_CPU]
356369

370+
def stop(self) -> None:
371+
"""Stop Darknet."""
372+
SubProcessWorker.stop(self)
373+
357374

358375
class DarknetNative(BaseDarknet, ChildProcessWorker):
359376
"""Darknet object detector interface using native Darknet.
@@ -454,7 +471,7 @@ def detect(
454471
return None
455472
return item["result"]
456473

457-
def post_process(self, detections, camera_resolution):
474+
def post_process(self, detections, camera_resolution) -> list[DetectedObject]:
458475
"""Post process detections."""
459476
_detections = []
460477
for label, confidence, box in detections:
@@ -493,3 +510,7 @@ def darknet_data_path(self) -> str:
493510
"""Return path to Darknet data file."""
494511
homedir = os.path.expanduser(f"~{pwd.getpwuid(os.geteuid())[0]}")
495512
return f"{homedir}/darknet_data.data"
513+
514+
def stop(self) -> None:
515+
"""Stop Darknet."""
516+
ChildProcessWorker.stop(self)

0 commit comments

Comments
 (0)