Spaces:
Sleeping
Sleeping
| """ | |
| GPU / backend detection utilities for OpenCV 5 DNN. | |
| OpenCV 5 engine selection strategy: | |
| ENGINE_AUTO β new graph engine (CPU-optimised, >80% ONNX coverage) | |
| ENGINE_CLASSIC β legacy 4.x engine (needed for CUDA backend today) | |
| ENGINE_ORT β delegate to ONNX Runtime (optional, enables TensorRT etc.) | |
| """ | |
| from __future__ import annotations | |
| import cv2 | |
| from src.utils.logger import get_logger | |
| log = get_logger(__name__) | |
| def get_dnn_backend_target(backend_name: str = "cpu") -> tuple[int, int]: | |
| """ | |
| Return the (backend, target) pair for cv2.dnn.Net. | |
| Args: | |
| backend_name: ``"cpu"`` | ``"cuda"`` | ``"opencl"`` | |
| Returns: | |
| Tuple of (cv2.dnn.DNN_BACKEND_*, cv2.dnn.DNN_TARGET_*). | |
| """ | |
| backend_name = backend_name.lower() | |
| if backend_name == "cuda": | |
| if _cuda_available(): | |
| log.info("CUDA backend selected") | |
| return cv2.dnn.DNN_BACKEND_CUDA, cv2.dnn.DNN_TARGET_CUDA | |
| else: | |
| log.warning("CUDA requested but not available, falling back to CPU") | |
| if backend_name == "opencl": | |
| log.info("OpenCL backend selected") | |
| return cv2.dnn.DNN_BACKEND_DEFAULT, cv2.dnn.DNN_TARGET_OPENCL | |
| log.info("CPU backend selected (OpenCV 5 graph engine)") | |
| return cv2.dnn.DNN_BACKEND_DEFAULT, cv2.dnn.DNN_TARGET_CPU | |
| def _cuda_available() -> bool: | |
| """Check whether OpenCV was compiled with CUDA support.""" | |
| try: | |
| info = cv2.getBuildInformation() | |
| return "CUDA" in info and "YES" in info[info.index("CUDA"):] | |
| except Exception: | |
| return False | |
| def get_engine_flag(engine_name: str = "auto") -> int | None: | |
| """ | |
| Return the ENGINE_* constant for cv2.dnn.readNet() if OpenCV 5 supports it. | |
| Falls back to None (which means OpenCV 4-style call without engine param). | |
| Args: | |
| engine_name: ``"auto"`` | ``"new"`` | ``"classic"`` | ``"ort"`` | |
| """ | |
| engine_name = engine_name.lower() | |
| engine_map = { | |
| "auto": getattr(cv2.dnn, "ENGINE_AUTO", None), | |
| "new": getattr(cv2.dnn, "ENGINE_NEW", None), | |
| "classic": getattr(cv2.dnn, "ENGINE_CLASSIC", None), | |
| "ort": getattr(cv2.dnn, "ENGINE_ORT", None), | |
| } | |
| flag = engine_map.get(engine_name) | |
| if flag is None and engine_name != "auto": | |
| log.warning( | |
| "ENGINE_%s not available in this OpenCV build β using ENGINE_AUTO", | |
| engine_name.upper(), | |
| ) | |
| return flag | |
| def log_system_info() -> None: | |
| """Log OpenCV build information relevant to DNN inference.""" | |
| log.info("OpenCV version: %s", cv2.__version__) | |
| build = cv2.getBuildInformation() | |
| for line in build.splitlines(): | |
| if any(kw in line for kw in ("CUDA", "ONNX", "Inference", "GPU", "OpenCL")): | |
| log.debug(" %s", line.strip()) | |