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

Сегментация по промпту

Сегментация по промпту превращает клик в маску: вы указываете на объект или обводите его рамкой, а модель возвращает его контур. В LibreYOLO это не отдельный ключ задачи, а группа моделей, которая загружается через фабрику LibreSAM и выдаёт обычные Results сегментации.

Определение

Сегментация по промпту принимает изображение и пространственный промпт и возвращает маску того, на что этот промпт указывает. Никакой классификации не происходит: списка классов нет, а result.boxes содержит рамки, плотно описанные вокруг масок, а не самостоятельные детекции. result.masks несёт данные масок, а result.masks.xy — их полигоны.

Интерфейс — это сам промпт. points — пиксельные координаты [x, y], по одному набору на объект, а labels помечает каждую точку как положительную (1, включить) или отрицательную (0, исключить). bboxes — это [x1, y1, x2, y2], одна маска на рамку. Точки и рамки можно комбинировать, тогда они соединяются попарно по объектам и должны быть одной длины. Если не передать ни одного промпта, запускается путь сегментации всего — сетка точек по изображению.

Одна точка неоднозначна по своей природе. Клик по рукаву может означать рукав, рубашку или человека, поэтому multimask=True возвращает на каждый промпт все три маски «целое против части» вместо одной лучшей. conf фильтрует по предсказанному моделью значению IoU — это оценка качества маски, а не уверенность детекции.

В LibreYOLO нет ключа задачи promptable. Группа регистрируется как segment — тот же ключ, что использует сегментация экземпляров. Отличается форма вызова, и поэтому у неё своя фабрика LibreSAM(), родственная LibreYOLO(), LibreOpenVocab() и LibreVLM(). Одной сигнатурой predict(image) не выразить тот цикл, ради которого эти модели и сделаны: set_image() один раз прогоняет кодировщик изображения и кэширует эмбеддинги, каждый следующий вызов predict() с source=None платит только за декодирование промпта, а reset_image() очищает кэш. Основные затраты приходятся на кодировщик изображения, а он выполняется один раз на изображение, так что второй промпт по тому же изображению пропускает его полностью.

Модели

Через LibreSAM по алиасу загружаются шесть семейств.

SAM — вариант по умолчанию, в размерах base, large и huge, они же b, l и h.

SAM 2 — как sam2-tiny, sam2-small, sam2-base-plus и sam2-large. LibreYOLO поддерживает его путь для изображений.

SAM 3, как sam3, — единственное семейство, которое принимает текстовый промпт-понятие: text="yellow school bus" возвращает все подходящие экземпляры. Передача text= любому другому семейству вызывает ошибку с сообщением, где названа модель SAM 3. Веса распространяет Meta под собственной лицензией SAM License, а не под MIT-лицензией LibreYOLO, и доступ к репозиторию ограничен: примите условия на странице модели и авторизуйтесь через hf auth login перед первой загрузкой. Прочитайте SAM 3, прежде чем разворачивать модель.

EdgeTAM, как edgetam, — вариант SAM 2 для работы на устройстве. LibreYOLO поддерживает его путь для изображений.

MobileSAM, как mobilesam, заменяет кодировщик ViT-H из SAM на дистиллированный TinyViT.

PicoSAM3, как picosam3, — компактная CNN для областей по промпту-рамке на периферийных сенсорах. Промпты рамкой здесь и есть весь контракт: точки, текст, маска, multimask и сегментация всего вызывают ошибку с сообщением, указывающим на SAM 2 или SAM 3.

Дополнительный набор зависимостей (extra) для этой группы охватывает четыре семейства, которые загружаются через transformers:

bash
pip install "libreyolo[sam]"

MobileSAM и PicoSAM3 — нативные порты в LibreYOLO, и для их запуска установка transformers не нужна.

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

Промпты точкой и рамкой
from libreyolo import LibreSAM, SAMPLE_IMAGE model = LibreSAM("base") # Точка — это [x, y] в пикселях; labels: 1 — положительная, 0 — отрицательная.result = model.predict(SAMPLE_IMAGE, points=[640, 420], labels=[1])print(result.masks.xy)      # полигоныprint(result.boxes.xyxy)    # рамки, плотно описанные вокруг масок # Промпт рамкой даёт одну маску на рамку.result = model.predict(SAMPLE_IMAGE, bboxes=[300, 200, 900, 700])
Одно кодирование, много промптов
from libreyolo import LibreSAM, SAMPLE_IMAGE model = LibreSAM("base") # set_image один раз прогоняет тяжёлый кодировщик изображения и кэширует его.model.set_image(SAMPLE_IMAGE)first = model.predict(points=[640, 420], labels=[1])second = model.predict(bboxes=[300, 200, 900, 700])model.reset_image()
Сегментация всего
from libreyolo import LibreSAM, SAMPLE_IMAGE model = LibreSAM("base") # Без промпта берётся сетка точек по всему изображению. Сетка по# умолчанию 32 на сторону — это ~1024 прохода декодера, медленно на CPU.result = model.predict(SAMPLE_IMAGE, points_per_side=8)print(len(result.masks))
Маски неоднозначности
from libreyolo import LibreSAM, SAMPLE_IMAGE model = LibreSAM("base") # Одна точка может означать рукав, рубашку или человека. multimask=True# возвращает все три маски «целое против части» вместо одной лучшей.result = model.predict(    SAMPLE_IMAGE, points=[640, 420], labels=[1], multimask=True)print(len(result.masks))

source и set_image() — альтернативы, а не последовательность: передайте изображение в predict() для разового вызова или сначала вызовите set_image(), а затем predict(source=None) на каждый промпт. Передача device= в predict() переносит модель для этого и всех последующих вызовов и делает недействительными закэшированные эмбеддинги.

Сегментация всего — дорогой режим. points_per_side по умолчанию равен 32, а это примерно 1024 прохода декодера по изображению; для интерактивных сценариев на CPU его стоит уменьшить. В этом режиме, если conf не задан, применяется пороговое значение сетки, принятое в этом семействе, а на пути с промптом незаданный conf оставляет все маски. Передайте conf=0.0, чтобы отключить фильтрацию в любом из режимов, и max_det, чтобы ограничить число возвращаемых масок.

Промпты маской в этой версии не поддерживаются, и masks= вызывает ошибку, а не игнорируется. track() тоже вызывает ошибку во всей группе: это сегментаторы изображений, поэтому запускайте predict() покадрово. Про источники и работу с результатами см. предсказание.

Обучение

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

Валидация

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

Экспорт

Экспорт для группы в целом не предусмотрен, и export() вызывает ошибку — с одним исключением. PicoSAM3 экспортирует в ONNX саму CNN для областей 96x96 как roi_image -> mask_logits; обрезка по рамке и обратное масштабирование маски в координаты изображения остаются в Python. Все остальные семейства работают через predict() в PyTorch. Про форматы, доступные в остальной библиотеке, см. экспорт.

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