SAM:Segment Anything 通用图像分割模型

FreeGuideOnline 最新 2026-06-20

SAM:Segment Anything 通用图像分割模型

SAM(Segment Anything Model)是 Meta AI 推出的图像分割基础模型。只需给出一个点、一个边界框、一段文字描述,或让模型自动发现,即可“分割一切”。本教程将带你从零掌握 SAM 的工作原理、使用方法与实际部署。

什么是 SAM?

SAM 实现了提示式分割。传统分割模型只能分割特定类别(如猫、狗),而 SAM 无需针对特定对象重新训练,只需极少提示即可分割任意物体。模型在包含超过 1100 万张图像、10 亿个掩码的 SA-1B 数据集上训练,实现了强大的零样本泛化能力。

核心能力:

  • 点提示:点击一个点,分割出包含该点的对象。
  • 框提示:画一个矩形框,分割框内主体。
  • 全自动分割:扫描全图,自动生成所有可能的分割掩码。
  • 多掩码输出:对模糊区域输出多个可信掩码(如衣服的领口与整件衣服)。

SAM 模型架构

SAM 由三个模块组成,彼此解耦,高效协作:

  • 图像编码器:基于 MAE 预训练的 ViT-H/16 视觉 Transformer,将图像一次性编码为特征嵌入。该模块计算量最大,但只需运行一次。
  • 提示编码器:将点、框、文本等提示编码为嵌入向量。点和框用位置编码表示,文本可选集成(官方版本不包含文本提示)。
  • 掩码解码器:一个轻量级 Transformer,交叉注意力融合图像嵌入与提示嵌入,输出分割掩码与置信度分数。对于模糊区域,会输出 3 个掩码(整体、部分、子部分)并附带分数。

这种分离设计使得同一张图像的嵌入可以反复用于不同提示,实现实时交互式分割。

快速上手:使用 SAM 分割图像

准备工作(Python 环境)

安装依赖:

pip install 'git+https://github.com/facebookresearch/segment-anything.git'
pip install opencv-python pycocotools matplotlib onnxruntime onnx

下载模型权重。Meta 提供三种尺寸的 ViT 模型:

  • vit_h:默认,精度最高,显存需求约 6-7 GB。
  • vit_l:平衡型。
  • vit_b:轻量快速,适合 CPU 或边缘设备。

以默认 vit_h 为例:

wget https://dl.fbaipublicfiles.com/segment_anything/sam_vit_h_4b8939.pth

基础代码:点提示分割

import cv2
import matplotlib.pyplot as plt
from segment_anything import sam_model_registry, SamPredictor

# 1. 加载模型
sam = sam_model_registry["vit_h"](checkpoint="sam_vit_h_4b8939.pth")
# 切换为预测模式(可指定 CPU 或 GPU)
predictor = SamPredictor(sam)
predictor.set_image(cv2.imread("your_image.jpg"))  # BGR 格式

# 2. 提供点提示:[ (x,y), ... ] 坐标,1 表示前景点,0 为背景点
input_point = np.array([[500, 375]])
input_label = np.array([1])

# 3. 预测
masks, scores, logits = predictor.predict(
    point_coords=input_point,
    point_labels=input_label,
    multimask_output=True,  # 输出3个备选掩码
)

# 4. 显示最佳掩码
best_mask = masks[np.argmax(scores)]
plt.imshow(best_mask, alpha=0.5)
plt.show()

如果不确定具体位置,可将 multimask_output=False,直接返回最高置信度唯一掩码。

框提示分割

# 输入框格式:[x_min, y_min, x_max, y_max]
input_box = np.array([200, 300, 600, 700])
masks, _, _ = predictor.predict(
    point_coords=None,
    point_labels=None,
    box=input_box[None, :],
    multimask_output=False,
)

全自动掩码生成

若要无交互提取所有对象,使用 SamAutomaticMaskGenerator

from segment_anything import sam_model_registry, SamAutomaticMaskGenerator

sam = sam_model_registry["vit_h"](checkpoint="sam_vit_h_4b8939.pth")
mask_generator = SamAutomaticMaskGenerator(sam)
masks = mask_generator.generate(cv2.imread("your_image.jpg"))
# masks 为字典列表,包含 segmentation, bbox, area, stability_score 等

自动生成时,模型会在图像上均匀采样点,经预测、非极大抑制和稳定性过滤,输出所有合理的分割区域。可通过调整参数控制粒度:

  • points_per_side:采样点数量(默认 32),越大越细。
  • pred_iou_thresh:掩码质量阈值,默认 0.88。
  • stability_score_thresh:稳定性阈值,默认 0.95。

应用场景与技巧

1. 批量数据集标注 用 SAM 预分割,人工修正边界,效率提升数倍。配合半自动交互,只需点击或框选目标,SAM 即可输出精确掩码。

2. 结合目标检测器 将 YOLO、Detic 等检测器的框作为 SAM 的提示,可一步生成实例分割结果。

3. 视频分割 逐帧运行 SAM 自动掩码生成,利用掩码面积和位置进行帧间关联,可搭建简单的视频目标分割流水线。

4. 边缘设备部署 SAM 支持 ONNX 导出,可在浏览器、移动端运行。官方提供 demo 前端,基于 ONNX Runtime Web 实现纯浏览器交互式分割。

局限性与注意事项

  • 文本提示尚未开放:论文提及文本提示,但公开模型未包含,需等待或通过第三方集成(如 Grounding DINO + SAM)。
  • 精细边界:对头发丝、复杂边缘可能不够精确,可结合抠图算法优化。
  • 密集小物体:全自动模式可能漏掉过小目标,可增大采样密度或使用检测器引导。
  • 实时性:图像编码器较重,单张图编码需数百毫秒,若需实时交互,可预先编码图像,利用缓存。

延伸学习

SAM 开启了基础模型在视觉感知领域的新范式,理解其提示式设计,能极大简化您的分割任务。立即尝试,用几行代码让任意物体“浮出水面”。