Посмотреть как Markdown

Оценка глубины

Оценка глубины предсказывает по одному изображению, насколько далеко от камеры находится каждый пиксель. В LibreYOLO это задача depth, которая возвращает плотную карту относительной обратной глубины на исходном холсте изображения.

Определение

Задача depth предсказывает по одному RGB-изображению одно значение на каждый пиксель. LibreYOLO определяет это значение как относительную обратную глубину: больше — ближе к камере, а у самих чисел нет ни метрических единиц, ни масштаба, который сохранялся бы между двумя изображениями. Сравнивать глубину двух пикселей одного предсказания осмысленно; сравнивать значение со значением с другого изображения — нет.

Предсказание заполняет result.depth_map — структуру DepthMap с массивом (H, W) на исходном холсте изображения. .min, .max и .mean читают конечные значения, а .normalized() приводит карту к [0, 1] для отображения. result.boxes остаётся пустым, поэтому conf, iou и max_det ни на что не влияют, а save=True записывает изображение карты в псевдоцветах, а не аннотированную фотографию.

Модели

Задачу depth обслуживают шесть семейств.

Depth Anything V2 сочетает энкодер DINOv2 с декодером DPT и служит здесь универсальным вариантом по умолчанию. Размер диктует лицензия не меньше, чем точность: чекпойнт Small идёт под Apache-2.0, а Base и Large — некоммерческие, так что перед выбором посмотрите таблицу чекпойнтов на его странице.

Depth Anything 3 портирует чекпойнт DA3MONO-LARGE — обычный трансформер без архитектурной специализации под глубину.

ZipDepth — компактный уровень: репараметризуемая CNN, дистиллированная из Depth Anything V2 Large, со вторым чекпойнтом, декодер которого обходится без операций gather и unfold — для NPU-компиляторов, где их нет.

MiDaS — та линия работ, которая задала zero-shot-протокол относительной глубины, по которому измеряют остальные семейства. Это единственное семейство глубины, которое LibreYOLO не публикует у себя: при запросе чекпойнта скачивается официальный файл из GitHub-релиза авторов и проверяется зафиксированный SHA-256.

LibreMODUS приходит к глубине как к одной из целей any-to-any-модели, а не через отдельную голову. Ему нужен extra modus и собственный аутентифицированный аккаунт Hugging Face, и он не предлагает ни val(), ни export().

SenseNova-Vision генерирует карту глубины как изображение через диффузионный декод — из того же 7B-чекпойнта, что обслуживает шесть остальных его задач. Ему нужен extra sensenova, а его веса ограничены некоммерческим использованием; лицензия — на его странице.

Предсказание

Веса скачиваются с Hugging Face при первом запуске и кэшируются локально — кроме двух семейств, отмеченных выше.

Предсказание карты глубины
from libreyolo import LibreYOLO, SAMPLE_IMAGE model = LibreYOLO("LibreDepthAnythingV2s-depth.pt")result = model(SAMPLE_IMAGE, save=True) depth = result.depth_mapprint(depth.data.shape)              # (H, W) на исходном холстеprint(depth.min, depth.max, depth.mean)
Работа со значениями
from libreyolo import LibreYOLO, SAMPLE_IMAGE model = LibreYOLO("LibreDepthAnythingV2s-depth.pt")result = model(SAMPLE_IMAGE) depth = result.depth_mapraw = depth.data          # больше — ближе; без метрических единиц и масштабаgray = depth.normalized() # приведено к [0, 1] для визуализацииprint(raw.shape, float(gray.max()))
Компактная альтернатива
from libreyolo import LibreYOLO, SAMPLE_IMAGE # Тот же контракт задачи, но сеть намного меньше — рассчитана на edge-среды выполнения.model = LibreYOLO("LibreZipDepthb-depth.pt")result = model(SAMPLE_IMAGE) print(result.depth_map.data.shape)

Разрешение входа ограничено по-своему в каждом семействе. Depth Anything V2 и Depth Anything 3 построены на сетке патчей DINOv2, поэтому imgsz должен нацело делиться на 14 — LibreYOLO проверяет это перед запуском. Results.plot() эту задачу не покрывает: он определён только для нормалей поверхности и краёв. Об источниках, стриминге и обработке результатов — в разделе предсказание.

Формат датасета

При валидации глубины каждому изображению соответствует плотная одноканальная карта глубины того же разрешения; путь к ней получается подстановкой каталога глубины в путь изображения.

dataset/
  data.yaml
  images/
    val/room.jpg
  depths/
    val/room.png
yaml
path: dataset
val: images/val
depths_dir: depths
nc: 1
names: {0: depth}

Карты — одноканальные PNG или TIF либо .npy. Значения — обычная глубина в единицах, единых для всего датасета, а пиксели 0, отрицательные, NaN и бесконечные помечают невалидные образцы, которые исключаются из метрик. Целочисленные карты делятся на depth_scale, по умолчанию 256.0 — соглашение для 16-битных PNG; карты .npy с плавающей точкой используются как есть. depth_stem_suffix и depth_mask_suffix покрывают датасеты, где файлы глубины или маски валидности называются иначе. Полный контракт — в разделе форматы датасетов.

Обучение

Ни у одного семейства глубины в LibreYOLO нет реализации обучения: train() выбрасывает NotImplementedError у всех шести. На странице каждой модели назван скрипт конвертации, который превращает чекпойнт, обученный в upstream-проекте, в чекпойнт, который может загрузить LibreYOLO.

Валидация

val() запускает общий валидатор глубины. У относительной глубины нет абсолютного масштаба, поэтому каждое предсказание сначала подгоняется к обратной величине своей эталонной разметки (ground truth) — масштаб и сдвиг подбираются методом наименьших квадратов отдельно для каждого изображения, — а затем обратным преобразованием возвращается к глубине. Каждая метрика ниже считается по такой выровненной карте для каждого изображения и усредняется по датасету, причём учитываются только пиксели, помеченные датасетом как валидные.

Валидация и чтение ключей метрик
from libreyolo import LibreYOLO model = LibreYOLO("LibreDepthAnythingV2s-depth.pt")metrics = model.val(data="my-dataset.yaml") print(metrics["metrics/abs_rel"])print(metrics["metrics/rmse"])print(metrics["metrics/delta1"])   # fitnessprint(metrics["metrics/delta2"], metrics["metrics/delta3"])

metrics/abs_rel — средняя абсолютная относительная ошибка, остаток, делённый на эталонную глубину; меньше — лучше. metrics/rmse — среднеквадратичная ошибка в собственных единицах глубины датасета, тоже меньше — лучше. metrics/delta1, metrics/delta2 и metrics/delta3 — пороговые accuracy: доля валидных пикселей, у которых отношение к эталону, взятое в ту сторону, где оно больше, оказывается меньше 1.25, 1.25 в квадрате и 1.25 в кубе, так что больше — лучше. metrics/delta1 — это ещё и fitness, число, по которому выбирается лучший чекпойнт.

Экспорт

Экспортированная модель глубины загружается обратно через LibreYOLO() по суффиксу файла, поэтому файл .onnx или .engine ведёт себя как чекпойнт и возвращает тот же Results, только с depth_map вместо рамок.

Экспорт
from libreyolo import LibreYOLO model = LibreYOLO("LibreDepthAnythingV2s-depth.pt")model.export(format="onnx")
Запуск экспортированного файла
from libreyolo import LibreYOLO, SAMPLE_IMAGE # Фабрика выбирает загрузчик по суффиксу файла, поэтому экспортированный# артефакт загружается как любой чекпойнт и возвращает тот же объект Results.model = LibreYOLO("LibreDepthAnythingV2s-depth.onnx")result = model(SAMPLE_IMAGE) print(result.depth_map.data.shape)

Покрытие различается по семействам, а Depth Anything 3 отклоняет любой формат вне своего проверенного набора, вместо того чтобы пытаться выполнить непроверенную конвертацию. Прежде чем остановиться на целевом формате, посмотрите страницу модели и полную матрицу экспорта. LibreMODUS и SenseNova-Vision не экспортируются вовсе. В разделе экспорт перечислены аргументы, которые принимает каждый формат.

Проверено с LibreYOLO v1.5.0.