mcpField
S
segment-anything-model

segment-anything-model

github.com/kalarislabs其他7342 次安装4 天前更新
代码仓库

关于 segment-anything-model

介绍如何使用 Meta AI 的 Segment Anything Model 进行零样本图像分割,面向视觉开发者。内容涵盖交互式提示、自动生成掩码、批处理和 ONNX 导出。

主要功能

  1. 01零样本图像分割
  2. 02点、框和掩码提示
  3. 03自动生成分割掩码
  4. 04批量处理图像与提示
  5. 05导出 ONNX 模型

适用场景

  1. 01构建交互式图像标注工具
  2. 02根据提示从图像中提取对象
  3. 03为医疗或卫星图像生成掩码
  4. 04导出模型以便通过 ONNX 部署

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/kalarislabs/research-agent-skills --skill segment-anything-model

安装后在 Claude Code 中输入/segment-anything-model确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
advanced-usage.md
interactive-segmentation.md
troubleshooting.md

详细介绍

Segment Anything Model(SAM)

Meta AI 的 Segment Anything Model 零样本图像分割综合指南。

何时使用 SAM

在以下情况下使用 SAM:

  • 无需针对特定任务进行训练,即可分割图像中的任意物体
  • 构建使用点或框提示词的交互式标注工具
  • 为其他视觉模型生成训练数据
  • 需要将零样本能力迁移到新的图像领域
  • 构建物体检测/分割流水线
  • 处理医学、卫星或特定领域的图像

主要特性:

  • 零样本分割:无需微调,即可处理任何图像领域
  • 灵活的提示词:点、边界框或先前的掩码
  • 自动分割:自动生成所有物体掩码
  • 高质量:使用来自 1,100 万张图像的 11 亿个掩码进行训练
  • 多种模型尺寸:ViT-B(最快)、ViT-L、ViT-H(最准确)
  • ONNX 导出:可部署到浏览器和边缘设备

可改用以下替代方案:

  • YOLO/Detectron2:用于带类别的实时物体检测
  • Mask2Former:用于带类别的语义/全景分割
  • GroundingDINO + SAM:用于文本提示的分割
  • SAM 2:用于视频分割任务

快速入门

安装
# From GitHub
pip install git+https://github.com/facebookresearch/segment-anything.git

# Optional dependencies
pip install opencv-python pycocotools matplotlib

# Or use HuggingFace transformers
pip install transformers
下载检查点
# ViT-H (largest, most accurate) - 2.4GB
wget https://dl.fbaipublicfiles.com/segment_anything/sam_vit_h_4b8939.pth

# ViT-L (medium) - 1.2GB
wget https://dl.fbaipublicfiles.com/segment_anything/sam_vit_l_0b3195.pth

# ViT-B (smallest, fastest) - 375MB
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

# Load model
sam = sam_model_registry["vit_h"](checkpoint="sam_vit_h_4b8939.pth")
sam.to(device="cuda")

# Create predictor
predictor = SamPredictor(sam)

# Set image (computes embeddings once)
image = cv2.imread("image.jpg")
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
predictor.set_image(image)

# Predict with point prompts
input_point = np.array([[500, 375]])  # (x, y) coordinates
input_label = np.array([1])  # 1 = foreground, 0 = background

masks, scores, logits = predictor.predict(
    point_coords=input_point,
    point_labels=input_label,
    multimask_output=True  # Returns 3 mask options
)

# Select best mask
best_mask = masks[np.argmax(scores)]
HuggingFace Transformers
import torch
from PIL import Image
from transformers import SamModel, SamProcessor

# Load model and processor
model = SamModel.from_pretrained("facebook/sam-vit-huge")
processor = SamProcessor.from_pretrained("facebook/sam-vit-huge")
model.to("cuda")

# Process image with point prompt
image = Image.open("image.jpg")
input_points = [[[450, 600]]]  # Batch of points

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

# Generate masks
with torch.no_grad():
    outputs = model(**inputs)

# Post-process masks to original size
masks = processor.image_processor.post_process_masks(
    outputs.pred_masks.cpu(),
    inputs["original_sizes"].cpu(),
    inputs["reshaped_input_sizes"].cpu()
)

核心概念

模型架构
SAM Architecture:
┌─────────────────┐     ┌─────────────────┐     ┌─────────────────┐
│  Image Encoder  │────▶│ Prompt Encoder  │────▶│  Mask Decoder   │
│     (ViT)       │     │ (Points/Boxes)  │     │ (Transformer)   │
└─────────────────┘     └─────────────────┘     └─────────────────┘
        │                       │                       │
   Image Embeddings      Prompt Embeddings         Masks + IoU
   (computed once)       (per prompt)             predictions
模型变体
模型检查点大小速度准确率
ViT-Hvit_h2.4 GB最慢最佳
ViT-Lvit_l1.2 GB中等良好
ViT-Bvit_b375 MB最快良好
提示词类型
提示词说明使用场景
点(前景)点击物体选择单个物体
点(背景)点击物体外部排除区域
边界框框住物体的矩形较大的物体
先前的掩码低分辨率掩码输入迭代优化

交互式分割

详细信息、代码示例和参数表:references/interactive-segmentation.md。在应用此步骤时阅读。

自动掩码生成

基本自动分割
from segment_anything import SamAutomaticMaskGenerator

# Create generator
mask_generator = SamAutomaticMaskGenerator(sam)

# Generate all masks
masks = mask_generator.generate(image)

# Each mask contains:
# - segmentation: binary mask
# - bbox: [x, y, w, h]
# - area: pixel count
# - predicted_iou: quality score
# - stability_score: robustness score
# - point_coords: generating point
自定义生成
mask_generator = SamAutomaticMaskGenerator(
    model=sam,
    points_per_side=32,          # Grid density (more = more masks)
    pred_iou_thresh=0.88,        # Quality threshold
    stability_score_thresh=0.95,  # Stability threshold
    crop_n_layers=1,             # Multi-scale crops
    crop_n_points_downscale_factor=2,
    min_mask_region_area=100,    # Remove tiny masks
)

masks = mask_generator.generate(image)
筛选掩码
# Sort by area (largest first)
masks = sorted(masks, key=lambda x: x['area'], reverse=True)

# Filter by predicted IoU
high_quality = [m for m in masks if m['predicted_iou'] > 0.9]

# Filter by stability score
stable_masks = [m for m in masks if m['stability_score'] > 0.95]

批量推理

多张图像
# Process multiple images efficiently
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)
每张图像使用多个提示词
# Process multiple prompts efficiently (one image encoding)
predictor.set_image(image)

# Batch of point prompts
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

# Load ONNX model
ort_session = onnxruntime.InferenceSession("sam_onnx.onnx")

# Run inference (image embeddings computed separately)
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

# Load model
predictor = SamPredictor(sam)
predictor.set_image(image)

def on_click(event, x, y, flags, param):
    if event == cv2.EVENT_LBUTTONDOWN:
        # Foreground point
        masks, scores, _ = predictor.predict(
            point_coords=np.array([[x, y]]),
            point_labels=np.array([1]),
            multimask_output=True
        )
        # Display best mask
        display_mask(masks[np.argmax(scores)])
工作流 2:物体提取
def extract_object(image, point):
    """Extract object at point with transparent background."""
    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)]

    # Create RGBA output
    rgba = np.zeros((image.shape[0], image.shape[1], 4), dtype=np.uint8)
    rgba[:, :, :3] = image
    rgba[:, :, 3] = best_mask * 255

    return rgba
工作流 3:医学图像分割
# Process medical images (grayscale to RGB)
medical_image = cv2.imread("scan.png", cv2.IMREAD_GRAYSCALE)
rgb_image = cv2.cvtColor(medical_image, cv2.COLOR_GRAY2RGB)

predictor.set_image(rgb_image)

# Segment region of interest
masks, scores, _ = predictor.predict(
    box=np.array([x1, y1, x2, y2]),  # ROI bounding box
    multimask_output=True
)

输出格式

掩码数据结构
# SamAutomaticMaskGenerator output
{
    "segmentation": np.ndarray,  # H×W binary mask
    "bbox": [x, y, w, h],        # Bounding box
    "area": int,                 # Pixel count
    "predicted_iou": float,      # 0-1 quality score
    "stability_score": float,    # 0-1 robustness score
    "crop_box": [x, y, w, h],    # Generation crop region
    "point_coords": [[x, y]],    # Input point
}
COCO RLE 格式
from pycocotools import mask as mask_utils

# Encode mask to RLE
rle = mask_utils.encode(np.asfortranarray(mask.astype(np.uint8)))
rle["counts"] = rle["counts"].decode("utf-8")

# Decode RLE to mask
decoded_mask = mask_utils.decode(rle)

性能优化

GPU 内存
# Use smaller model for limited VRAM
sam = sam_model_registry["vit_b"](checkpoint="sam_vit_b_01ec64.pth")

# Process images in batches
# Clear CUDA cache between large batches
torch.cuda.empty_cache()
速度优化
# Use half precision
sam = sam.half()

# Reduce points for automatic generation
mask_generator = SamAutomaticMaskGenerator(
    model=sam,
    points_per_side=16,  # Default is 32
)

# Use ONNX for deployment
# Export with --return-single-mask for faster inference

常见问题

问题解决方案
内存不足使用 ViT-B 模型,缩小图像尺寸
推理速度慢使用 ViT-B,减小 points_per_side
掩码质量差尝试不同的提示词,组合使用框和点
边缘伪影使用 stability_score 筛选
漏检小物体增大 points_per_side

参考资料

资源

Agent 操作流程

  1. 检查环境。 确认 GPU 内存、模型检查点和许可证、框架版本及输入格式。
  2. 明确输入。 根据数据或用户确认格式、标识符和参数。任何会改变结果的值都应询问,不要猜测。
  3. 先运行小规模版本。 先以低分辨率或较短长度对单个样本运行推理。
  4. 使用上述说明和参考资料执行完整任务。
  5. 验证结果。 使用任务指标进行定性检查并查看输出;检查生成内容的许可证限制。
  6. 报告。 说明运行了什么(版本、命令、参数)、检查了什么,以及还有哪些不确定之处。
如果发生这种情况请这样做
大型输入导致内存不足降低分辨率或序列长度、使用半精度,或对输入进行分块处理。
这些说明中的函数、标志或端点在已安装的版本中不存在查阅已安装版本自己的文档(help()、--help、官方文档),进行调整并告知用户。切勿编造 API。
必需的输入、标识符或参数不明确询问用户,或在运行前明确说明所作的假设。

诚信规则

  • 切勿编造结果、参数、标识符、引用或统计数据。如果无法运行或验证某项内容,请明确说明。
  • 在用于商业用途或发布之前,检查模型和数据集的许可证。
  • 此处与版本相关的细节可能已经过时:请对照已安装版本的官方文档进行确认。
  • 对于需要付费、占用共享 GPU 或云配额、涉及个人或患者数据,或无法撤销的操作,请先征得同意。

相关技能

  • clip:OpenAI 的视觉与语言连接模型。
  • generate-image:通过 OpenRouter Image API(Gemini、Seedream、Recraft、GPT-Image、Riverflow)使用 AI 模型生成或编辑图像。
  • blip-2-vision-language:说明如何通过 HuggingFace Trans… 使用 Salesforce BLIP-2(Q-Former 连接冻结的图像编码器与 OPT 或 FlanT5 等 LLM)。

评论

支持 Markdown