Оценка глубины
Оценка глубины предсказывает по одному изображению, насколько далеко от камеры находится каждый пиксель. В 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.pngpath: 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 не экспортируются вовсе. В разделе экспорт перечислены аргументы, которые принимает каждый формат.