Перейти к основному содержимому

Segment Anything Model

SAM: сегментация изображений zero-shot по точкам, рамкам и маскам.

Метаданные навыка​

ИсточникВстроенный (установлен по умолчанию)
Путьskills/mlops/models/segment-anything
Версия1.0.0
АвторOrchestra Research
ЛицензияMIT
Зависимостиsegment-anything, transformers>=4.30.0, torch>=1.7.0
Платформыlinux, macos, windows
ТегиMultimodal, Image Segmentation, Computer Vision, SAM, Zero-Shot

Справочник: полный SKILL.md​

к сведению

Ниже приведено полное описание навыка, которое VibeOS загружает при активации этого навыка. Агент видит эти инструкции, когда навык активен.

Segment Anything Model (SAM)

Подробное руководство по использованию модели Segment Anything от Meta AI для сегментации изображений zero-shot.

Когда использовать SAM​

Используйте SAM, когда:

  • Нужно сегментировать любой объект на изображениях без специального обучения
  • Создаются интерактивные инструменты аннотации с точечными/рамными подсказками
  • Генерируются обучающие данные для других моделей компьютерного зрения
  • Требуется zero-shot перенос на новые домены изображений
  • Строятся пайплайны обнаружения/сегментации объектов
  • Обрабатываются медицинские, спутниковые или специализированные изображения

Ключевые особенности:

  • Zero-shot сегментация: работает в любом домене изображений без дообучения
  • Гибкие подсказки: точки, ограничивающие рамки или предыдущие маски
  • Автоматическая сегментация: генерирует все маски объектов автоматически
  • Высокое качество: обучена на 1,1 миллиарда масок из 11 миллионов изображений
  • Несколько размеров модели: ViT-B (самая быстрая), ViT-L, ViT-H (самая точная)
  • Экспорт в ONNX: развертывание в браузерах и на периферийных устройствах

Используйте альтернативы, если:

  • YOLO/Detectron2: для обнаружения объектов в реальном времени с классами
  • Mask2Former: для семантической/панорамной сегментации с категориями
  • GroundingDINO + SAM: для сегментации по текстовым подсказкам
  • SAM 2: для задач сегментации видео

Быстрый старт​

Установка​

# Из GitHub
pip install git+https://github.com/facebookresearch/segment-anything.git

# Опциональные зависимости
pip install opencv-python pycocotools matplotlib

# Или используйте HuggingFace transformers
pip install transformers

Загрузка контрольных точек​

# ViT-H (самая большая, самая точная) — 2,4 ГБ
wget https://dl.fbaipublicfiles.com/segment_anything/sam_vit_h_4b8939.pth

# ViT-L (средняя) — 1,2 ГБ
wget https://dl.fbaipublicfiles.com/segment_anything/sam_vit_l_0b3195.pth

# ViT-B (самая маленькая, самая быстрая) — 375 МБ
wget https://dl.fbaipublicfiles.com/segment_anything/sam_vit_b_01ec64.pth

Базовое использование с SamPredictor​

import numpy as np
from segment_anything import sam_model_registry, SamPredictor

# Загрузка модели
sam = sam_model_registry`"vit_h"`
sam.to(device="cuda")

# Создание предиктора
predictor = SamPredictor(sam)

# Установка изображения (вычисляет эмбеддинги один раз)
image = cv2.imread("image.jpg")
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
predictor.set_image(image)

# Предсказание с точечными подсказками
input_point = np.array([[500, 375]]) # координаты (x, y)
input_label = np.array([1]) # 1 = передний план, 0 = фон

masks, scores, logits = predictor.predict(
point_coords=input_point,
point_labels=input_label,
multimask_output=True # Возвращает 3 варианта маски
)

# Выбор лучшей маски
best_mask = masks[np.argmax(scores)]

HuggingFace Transformers​

import torch
from PIL import Image
from transformers import SamModel, SamProcessor

# Загрузка модели и процессора
model = SamModel.from_pretrained("facebook/sam-vit-huge")
processor = SamProcessor.from_pretrained("facebook/sam-vit-huge")
model.to("cuda")

# Обработка изображения с точечной подсказкой
image = Image.open("image.jpg")
input_points = [[[450, 600]]] # Пакет точек

inputs = processor(image, input_points=input_points, return_tensors="pt")
inputs = {k: v.to("cuda") for k, v in inputs.items()}

# Генерация масок
with torch.no_grad():
outputs = model(**inputs)

# Постобработка масок до исходного размера
masks = processor.image_processor.post_process_masks(
outputs.pred_masks.cpu(),
inputs["original_sizes"].cpu(),
inputs["reshaped_input_sizes"].cpu()
)

Основные концепции​

Архитектура модели​

Архитектура SAM:
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Кодировщик │────▶│ Кодировщик │────▶│ Декодер масок │
│ изображений │ │ подсказок │ │ (Transformer) │
│ (ViT) │ │ (Точки/Рамки) │ │ │
└─────────────────┘ └─────────────────┘ └─────────────────┘
│ │ │
Эмбеддинги Эмбеддинги Маски + IoU
изображений подсказок предсказания
(вычисляются (на каждую
один раз) подсказку)

Варианты модели​

МодельКонтрольная точкаРазмерСкоростьТочность
ViT-Hvit_h2,4 ГБСамая медленнаяЛучшая
ViT-Lvit_l1,2 ГБСредняяХорошая
ViT-Bvit_b375 МБСамая быстраяХорошая

Типы подсказок​

ПодсказкаОписаниеСценарий использования
Точка (передний план)Клик по объектуВыбор одного объекта
Точка (фон)Клик вне объектаИсключение областей
Ограничивающая рамкаПрямоугольник вокруг объектаКрупные объекты
Предыдущая маскаВходная маска низкого разрешенияИтеративное уточнение

Интерактивная сегментация​

Точечные подсказки​

# Одна точка переднего плана
input_point = np.array([[500, 375]])
input_label = np.array([1])

masks, scores, logits = predictor.predict(
point_coords=input_point,
point_labels=input_label,
multimask_output=True
)

# Несколько точек (передний план + фон)
input_points = np.array([[500, 375], [600, 400], [450, 300]])
input_labels = np.array([1, 1, 0]) # 2 переднего плана, 1 фон

masks, scores, logits = predictor.predict(
point_coords=input_points,
point_labels=input_labels,
multimask_output=False # Одна маска, когда подсказки ясны
)

Рамные подсказки​

# Ограничивающая рамка [x1, y1, x2, y2]
input_box = np.array([425, 600, 700, 875])

masks, scores, logits = predictor.predict(
box=input_box,
multimask_output=False
)

Комбинированные подсказки​

# Рамка + точки для точного контроля
masks, scores, logits = predictor.predict(
point_coords=np.array([[500, 375]]),
point_labels=np.array([1]),
box=np.array([400, 300, 700, 600]),
multimask_output=False
)

Итеративное уточнение​

# Первоначальное предсказание
masks, scores, logits = predictor.predict(
point_coords=np.array([[500, 375]]),
point_labels=np.array([1]),
multimask_output=True
)

# Уточнение с дополнительной точкой с использованием предыдущей маски
masks, scores, logits = predictor.predict(
point_coords=np.array([[500, 375], [550, 400]]),
point_labels=np.array([1, 0]), # Добавление фоновой точки
mask_input=logits[np.argmax(scores)][None, :, :], # Использование лучшей маски
multimask_output=False
)

Автоматическая генерация масок​

Базовая автоматическая сегментация​

from segment_anything import SamAutomaticMaskGenerator

# Создание генератора
mask_generator = SamAutomaticMaskGenerator(sam)

# Генерация всех масок
masks = mask_generator.generate(image)

# Каждая маска содержит:
# - segmentation: бинарная маска
# - bbox: [x, y, w, h]
# - area: количество пикселей
# - predicted_iou: оценка качества
# - stability_score: оценка устойчивости
# - point_coords: генерирующая точка

Настраиваемая генерация​

mask_generator = SamAutomaticMaskGenerator(
model=sam,
points_per_side=32, # Плотность сетки (больше = больше масок)
pred_iou_thresh=0.88, # Порог качества
stability_score_thresh=0.95, # Порог устойчивости
crop_n_layers=1, # Многомасштабные обрезки
crop_n_points_downscale_factor=2,
min_mask_region_area=100, # Удаление маленьких масок
)

masks = mask_generator.generate(image)

Фильтрация масок​

# Сортировка по площади (сначала самые большие)
masks = sorted(masks, key=lambda x: x['area'], reverse=True)

# Фильтрация по предсказанному IoU
high_quality = [m for m in masks if m['predicted_iou'] > 0.9]

# Фильтрация по оценке устойчивости
stable_masks = [m for m in masks if m['stability_score'] > 0.95]

Пакетный вывод​

Несколько изображений​

# Эффективная обработка нескольких изображений
images = [cv2.imread(f"image_{i}.jpg") for i in range(10)]

all_masks = []
for image in images:
predictor.set_image(image)
masks, _, _ = predictor.predict(
point_coords=np.array([[500, 375]]),
point_labels=np.array([1]),
multimask_output=True
)
all_masks.append(masks)

Несколько подсказок на изображение​

# Эффективная обработка нескольких подсказок (одно кодирование изображения)
predictor.set_image(image)

# Пакет точечных подсказок
points = [
np.array([[100, 100]]),
np.array([[200, 200]]),
np.array([[300, 300]])
]

all_masks = []
for point in points:
masks, scores, _ = predictor.predict(
point_coords=point,
point_labels=np.array([1]),
multimask_output=True
)
all_masks.append(masks[np.argmax(scores)])

Развертывание ONNX​

Экспорт модели​

python scripts/export_onnx_model.py \
--checkpoint sam_vit_h_4b8939.pth \
--model-type vit_h \
--output sam_onnx.onnx \
--return-single-mask

Использование модели ONNX​

import onnxruntime

# Загрузка модели ONNX
ort_session = onnxruntime.InferenceSession("sam_onnx.onnx")

# Запуск вывода (эмбеддинги изображений вычисляются отдельно)
masks = ort_session.run(
None,
{
"image_embeddings": image_embeddings,
"point_coords": point_coords,
"point_labels": point_labels,
"mask_input": np.zeros((1, 1, 256, 256), dtype=np.float32),
"has_mask_input": np.array([0], dtype=np.float32),
"orig_im_size": np.array([h, w], dtype=np.float32)
}
)

Типовые рабочие процессы​

Рабочий процесс 1: Инструмент аннотации​

import cv2

# Загрузка модели
predictor = SamPredictor(sam)
predictor.set_image(image)

def on_click(event, x, y, flags, param):
if event == cv2.EVENT_LBUTTONDOWN:
# Точка переднего плана
masks, scores, _ = predictor.predict(
point_coords=np.array([[x, y]]),
point_labels=np.array([1]),
multimask_output=True
)
# Отображение лучшей маски
display_mask(masks[np.argmax(scores)])

Рабочий процесс 2: Извлечение объекта​

def extract_object(image, point):
"""Извлечение объекта в точке с прозрачным фоном."""
predictor.set_image(image)

masks, scores, _ = predictor.predict(
point_coords=np.array([point]),
point_labels=np.array([1]),
multimask_output=True
)

best_mask = masks[np.argmax(scores)]

# Создание RGBA вывода
rgba = np.zeros((image.shape[0], image.shape[1], 4), dtype=np.uint8)
rgba[:, :, :3] = image
rgba[:, :, 3] = best_mask * 255

return rgba

Рабочий процесс 3: Сегментация медицинских изображений​

# Обработка медицинских изображений (оттенки серого в RGB)
medical_image = cv2.imread("scan.png", cv2.IMREAD_GRAYSCALE)
rgb_image = cv2.cvtColor(medical_image, cv2.COLOR_GRAY2RGB)

predictor.set_image(rgb_image)

# Сегментация области интереса
masks, scores, _ = predictor.predict(
box=np.array([x1, y1, x2, y2]), # Ограничивающая рамка ROI
multimask_output=True
)

Формат вывода​

Структура данных маски​

# Вывод SamAutomaticMaskGenerator
{
"segmentation": np.ndarray, # Бинарная маска H×W
"bbox": [x, y, w, h], # Ограничивающая рамка
"area": int, # Количество пикселей
"predicted_iou": float, # Оценка качества 0-1
"stability_score": float, # Оценка устойчивости 0-1
"crop_box": [x, y, w, h], # Область обрезки генерации
"point_coords": [[x, y]], # Входная точка
}

Формат COCO RLE​

from pycocotools import mask as mask_utils

# Кодирование маски в RLE
rle = mask_utils.encode(np.asfortranarray(mask.astype(np.uint8)))
rle["counts"] = rle["counts"].decode("utf-8")

# Декодирование RLE в маску
decoded_mask = mask_utils.decode(rle)

Оптимизация производительности​

Память GPU​

# Использование меньшей модели для ограниченной VRAM
sam = sam_model_registry`"vit_b"`

# Обработка изображений пакетами
# Очистка кэша CUDA между большими пакетами
torch.cuda.empty_cache()

Оптимизация скорости​

# Использование половинной точности
sam = sam.half()

# Уменьшение количества точек для автоматической генерации
mask_generator = SamAutomaticMaskGenerator(
model=sam,
points_per_side=16, # По умолчанию 32
)

# Использование ONNX для развертывания
# Экспорт с --return-single-mask для более быстрого вывода

Частые проблемы​

ПроблемаРешение
Нехватка памятиИспользуйте модель ViT-B, уменьшите размер изображения
Медленный выводИспользуйте ViT-B, уменьшите points_per_side
Плохое качество маскиПопробуйте другие подсказки, используйте рамку + точки
Артефакты на краяхИспользуйте фильтрацию по stability_score
Мелкие объекты пропущеныУвеличьте points_per_side

Ссылки​

  • Расширенное использование — Пакетная обработка, дообучение, интеграция
  • Устранение неполадок — Частые проблемы и решения

Ресурсы​