OpenCV 5: новый DNN-движок, 80% ONNX и что проверить перед обновлением

Знак «Стоп» с двумя рамками детектора: эталонной и предсказанной

Если вы делаете распознавание на своих камерах, то OpenCV почти наверняка уже есть в проекте: захват кадра, ресайз, рисование рамок. Теперь у библиотеки вышло новое мажорное поколение, и самое интересное в нём — переписанный DNN-модуль, который читает нейросети в формате ONNX. Разберём, что именно изменилось и что стоит проверить до перехода с ветки 4.x.

Знак «Стоп» с двумя рамками детектора: эталонной и предсказанной
Фото: Adrian Rosebrock, Wikimedia Commons, CC BY-SA 4.0

Что вышло и когда

Релиз OpenCV 5.0.0 опубликован на GitHub 6 июня 2026 года, он помечен там как Latest. В официальном обзоре сказано, что выпуск приурочили к конференции CVPR 2026, а pip-сборку обещали на 8 июня. При этом на странице релизов выше стоит 4.14.0 от 19 июля, то есть ветка 4.x продолжает жить параллельно. Релизов 5.x после 5.0.0 на момент проверки (30 октября 2026) я там не увидел, так что «свежая» новость здесь скорее итог первых месяцев: у версии было время обрасти статьями и примерами.

Главное: новый DNN-движок

По данным обзора на opencv.org, покрытие операторов ONNX выросло примерно с 22% в серии 4.x до более 80%. Новый движок построен на графе и поддерживает ветвления и циклы (If/Loop), динамические формы, квантованные модели (QDQ) и слияние операторов, в том числе блоков attention. На практике это значит, что современные модели — трансформерные детекторы вроде RF-DETR и подобные — должны загружаться без плясок с упрощением графа, которые часто приходилось делать в 4.x.

Для совместимости движков теперь три, и выбирать их можно параметром engine при чтении сети:

  • ENGINE_CLASSIC — прежний движок;
  • ENGINE_NEW — новый графовый;
  • ENGINE_AUTO — значение по умолчанию: OpenCV сам решает, чем читать модель;
  • ENGINE_ORT — через ONNX Runtime, нужна сборка с WITH_ONNXRUNTIME=ON.

Важная оговорка из того же обзора: новый движок пока работает только на CPU, GPU-поддержку в нём обещают в версиях 5.x. Для ESP32 это не актуально, а вот для мини-ПК, Raspberry Pi или сервера без видеокарты — как раз тот случай, где CPU-инференс и нужен. Авторы заявляют, что на CPU новый движок обгоняет ONNX Runtime на ряде моделей (YOLOv8, DINOv2, RF-DETR, OWLv2); это цифры самого проекта, а не мои замеры, так что проверяйте на своём железе.

Что ещё поменялось

  • LLM и VLM в DNN. Добавлены встроенный токенизатор и KV-cache; заявлены Qwen 2.5, Gemma 3, PaliGemma и семейство GPT-2. Для умного дома это скорее любопытство, чем замена Ollama, но подпись к кадру без отдельной зависимости — интересная идея.
  • Новые типы данных. FP16 (CV_16F), BF16 (CV_16BF), bool, int64; Mat умеет 0D и 1D.
  • Модуль Features заменяет Features2D: добавлены ALIKED, DISK и LightGlueMatcher. Классические SIFT, ORB, FAST остаются, а редкие алгоритмы переехали в opencv_contrib.
  • 3D разделено на модули 3d, calib и stereo.
  • Python: совместимость с NumPy 2.x и именованные аргументы.
  • Сборка: минимальный стандарт C++17, старый C API помечен как устаревший.

Практика: как безопасно попробовать

Самый разумный путь — не обновлять рабочую систему, а завести отдельное окружение и прогнать свои модели в обоих движках. Для миграции у проекта есть отдельная страница в вики: «OpenCV 4 to 5 migration». Прочитайте её до обновления, особенно если в коде есть вызовы Features2D или старого C API.

python3 -m venv ~/venv-cv5
. ~/venv-cv5/bin/activate
pip install opencv-python numpy
python -c "import cv2; print(cv2.__version__)"

Убедитесь, что выведена версия 5.x: имя пакета и его версию лучше сверить на странице PyPI, я их в источниках не нашёл. Дальше — сравнение движков на вашей ONNX-модели. Ниже набросок; точные имена констант и параметров сверьте с документацией вашей версии, так как я опираюсь на описание из обзора:

import time, cv2, numpy as np

MODEL = "model.onnx"          # ваша модель, например экспорт YOLO
img = np.random.rand(1, 3, 640, 640).astype(np.float32)

for name in ("ENGINE_CLASSIC", "ENGINE_NEW", "ENGINE_AUTO"):
    net = cv2.dnn.readNetFromONNX(MODEL, getattr(cv2.dnn, name))
    net.setInput(img)
    net.forward()                # прогрев
    t = time.perf_counter()
    for _ in range(20):
        net.forward()
    print(name, round((time.perf_counter() - t) / 20 * 1000, 1), "мс")

Если какой-то движок не поймёт вашу модель, это будет видно сразу по ошибке на чтении. Заодно сверьте результаты: пороги и NMS остаются вашей заботой, а вот выходной тензор у разных движков должен совпадать по форме и значениям с точностью до погрешности.

Выводы

OpenCV 5 — это в первую очередь обновление для тех, кто гоняет нейросети на CPU: больше поддерживаемых операторов, меньше ручной подготовки ONNX, хороший шанс ускорить инференс без смены библиотеки. Для проектов, где OpenCV нужен только для захвата и рисования, срочности нет: ветка 4.x по-прежнему получает релизы. Мой план — завести отдельное окружение, прогнать свою детекцию на двух движках и только потом решать, переходить ли.

Источники

Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *