基于SAM3大模型镜像实现文本引导视频目标分割与跟踪

1. 引言:从图像到视频的万物分割演进

随着计算机视觉技术的发展,目标分割已从静态图像处理逐步迈向动态视频理解。传统的视频目标分割方法通常依赖大量标注数据和复杂的训练流程,难以适应开放世界中“任意目标”的分割需求。而 SAM3(Segment Anything Model 3) 的出现彻底改变了这一局面。

SAM3 是 Meta 推出的第三代“万物可分割”模型,在继承前代强大零样本泛化能力的基础上,进一步增强了对视频序列的时序建模能力。结合 CSDN 提供的 sam3 提示词引导万物分割模型 镜像,用户无需部署复杂环境,即可通过自然语言提示(如 "dog", "red car")快速实现跨帧目标识别、精细区域控制与持续跟踪。

本文将围绕该镜像展开,详细介绍如何利用 SAM3 实现:

  • 文本引导的视频目标自动分割
  • 点提示精准添加/修正目标
  • 跨帧目标跟踪与 ID 管理
  • 正负样本协同优化分割精度

所有操作均可在 WebUI 或源码层面完成,适合研究者、开发者及 AI 应用工程师快速集成落地。


2. 环境准备与镜像使用说明

2.1 镜像核心配置

本镜像基于生产级环境构建,确保高性能推理与高兼容性支持:

组件版本
Python3.12
PyTorch2.7.0+cu126
CUDA / cuDNN12.6 / 9.x
代码路径/root/sam3

该配置支持 A10、V100、3090 等主流 GPU 设备,兼顾计算效率与显存利用率。

2.2 启动方式选择

方式一:WebUI 可视化交互(推荐新手)
  1. 实例启动后等待 10–20 秒,系统自动加载模型;
  2. 点击右侧控制面板中的 “WebUI” 按钮;
  3. 在网页界面上传图片或视频,输入英文描述语(Prompt),点击 “开始执行分割” 即可。

注意:目前仅支持英文 Prompt,建议使用常见名词,如 person, car, bottle

方式二:命令行手动重启服务

若需重新启动应用,可执行以下命令:

/bin/bash /usr/local/bin/start-sam3.sh

此脚本会拉起 Gradio Web 服务并加载预训练权重,适用于调试或自定义修改场景。


3. 核心功能解析:SAM3 视频分割机制

3.1 多模态提示驱动的分割范式

SAM3 的核心创新在于其 多模态提示机制(Multi-modal Prompting),允许用户通过多种方式指定待分割目标:

  • 文本提示(Text Prompt):输入类别名称,如 "cat",模型自动定位并分割对应物体。
  • 点提示(Point Prompt):在图像上点击一点,指示“此处是目标”或“非目标”。
  • 框提示(Box Prompt):绘制边界框限定搜索范围。
  • 掩码提示(Mask Prompt):提供粗略掩码以引导精细化输出。

这些提示不仅作用于单帧图像,还能作为“种子”在整个视频中进行跨帧传播与跟踪。

3.2 视频感知架构设计

SAM3 在原始 SAM 架构基础上引入了 Temporal Encoder-Decoder 结构,专门用于建模帧间一致性。其主要特点包括:

  • 记忆库(Memory Bank)机制:存储历史帧的目标特征,用于后续帧的匹配与追踪;
  • 光流对齐模块:补偿摄像机运动或目标位移带来的像素偏移;
  • 动态更新策略:根据置信度决定是否刷新目标表征,避免漂移。

这使得 SAM3 能够在不依赖额外跟踪器的情况下,实现稳定、连贯的视频目标分割。


4. 实战演练:视频目标分割全流程

4.1 准备工作:导入依赖库

首先加载必要的 Python 包:

import cv2
import torch
import numpy as np
import supervision as sv
from pathlib import Path
from PIL import Image
from typing import Optional
from IPython.display import Video
from sam3.model_builder import build_sam3_video_predictor
import os
import glob
import matplotlib.pyplot as plt
from sam3.visualization_utils import (
    load_frame,
    prepare_masks_for_visualization,
    visualize_formatted_frame_output,
)

其中 supervision 用于可视化,sam3.* 为模型核心接口。

4.2 定义辅助函数

为提升代码复用性,定义两个关键工具函数:

# 设置绘图字体大小
plt.rcParams["axes.titlesize"] = 12
plt.rcParams["figure.titlesize"] = 12

# 从第0帧传播至视频末尾
def propagate_in_video(predictor, session_id):
    outputs_per_frame = {}
    for response in predictor.handle_stream_request(
        request=dict(
            type="propagate_in_video",
            session_id=session_id,
        )
    ):
        outputs_per_frame[response["frame_index"]] = response["outputs"]
    return outputs_per_frame

# 坐标归一化:绝对坐标 → 相对坐标(0~1)
def abs_to_rel_coords(coords, IMG_WIDTH, IMG_HEIGHT, coord_type="point"):
    if coord_type == "point":
        return [[x / IMG_WIDTH, y / IMG_HEIGHT] for x, y in coords]
    elif coord_type == "box":
        return [
            [x / IMG_WIDTH, y / IMG_HEIGHT, w / IMG_WIDTH, h / IMG_HEIGHT]
            for x, y, w, h in coords
        ]
    else:
        raise ValueError(f"Unknown coord_type: {coord_type}")

4.3 加载 SAM3 模型

初始化视频预测器,并加载预训练权重:

DEVICES = [torch.cuda.current_device()]  # 使用当前GPU

checkpoint_path = "models/sam3.pt"
bpe_path = "assets/bpe_simple_vocab_16e6.txt.gz"

predictor = build_sam3_video_predictor(
    checkpoint_path=checkpoint_path,
    bpe_path=str(bpe_path),
    gpus_to_use=DEVICES
)

模型首次加载耗时约 10–15 秒,之后即可高效处理视频流。

4.4 视频预处理:拆分为帧序列

使用 ffmpeg 将视频切分为独立图像帧,便于逐帧访问:

SOURCE_VIDEO = "assets/videos/bedroom.mp4"
output_dir = 'output2'
os.makedirs(output_dir, exist_ok=True)

!ffmpeg -i {SOURCE_VIDEO} -q:v 2 -start_number 0 output2/%05d.jpg

生成的帧文件命名格式为 00000.jpg, 00001.jpg...,按数字排序保证时序正确。

4.5 读取视频帧用于可视化

将图像帧加载为 RGB 数组列表:

video_path = "output2"
video_frames_for_vis = sorted(
    glob.glob(os.path.join(video_path, "*.jpg")),
    key=lambda p: int(os.path.splitext(os.path.basename(p))[0])
)

后续可通过索引直接访问任意帧内容。

4.6 初始化视频处理会话

创建一个会话上下文,用于管理目标状态与跟踪信息:

response = predictor.handle_request(
    request=dict(
        type="start_session",
        resource_path=SOURCE_VIDEO,
    )
)
session_id = response["session_id"]

重要提示:每次新任务应调用 reset_session 清除旧状态,防止干扰。

_ = predictor.handle_request(
    request=dict(
        type="reset_session",
        session_id=session_id,
    )
)

5. 分割方法详解

5.1 方法一:文本提示实现类别级分割

只需输入目标类别的英文名称,即可触发自动检测与分割:

prompt_text_str = "person"
frame_idx = 0

response = predictor.handle_request(
    request=dict(
        type="add_prompt",
        session_id=session_id,
        frame_index=frame_idx,
        text=prompt_text_str,
    )
)
out = response["outputs"]

随后调用 propagate_in_video 进行全视频传播:

outputs_per_frame = propagate_in_video(predictor, session_id)
outputs_per_frame = prepare_masks_for_visualization(outputs_per_frame)

# 每60帧可视化一次结果
vis_frame_stride = 60
for frame_idx in range(0, len(outputs_per_frame), vis_frame_stride):
    visualize_formatted_frame_output(
        frame_idx,
        video_frames_for_vis,
        outputs_list=[outputs_per_frame],
        titles=["SAM 3 Dense Tracking outputs"],
        figsize=(6, 4),
    )

此时模型会在整个视频中持续跟踪所有符合 "person" 描述的目标。

5.2 移除指定目标(按 ID 操作)

若某目标误检或不再关注,可通过其唯一 ID 移除:

obj_id = 1  # 如小女孩
predictor.handle_request(
    request=dict(
        type="remove_object",
        session_id=session_id,
        obj_id=obj_id,
    )
)

# 重新传播验证效果
outputs_per_frame = propagate_in_video(predictor, session_id)

移除后该目标不再参与后续帧的跟踪与渲染。

5.3 方法二:点提示添加精确目标

对于文本无法区分的具体实例,可用点提示精确定位:

sample_img = Image.fromarray(load_frame(video_frames_for_vis[0]))
IMG_WIDTH, IMG_HEIGHT = sample_img.size

frame_idx = 0
obj_id = 1
points_abs = np.array([[406, 170]])  # 目标中心点
labels = np.array([1])  # 1 表示正样本

points_tensor = torch.tensor(
    abs_to_rel_coords(points_abs, IMG_WIDTH, IMG_HEIGHT, "point"),
    dtype=torch.float32,
)
points_labels_tensor = torch.tensor(labels, dtype=torch.int32)

predictor.handle_request(
    request=dict(
        type="add_prompt",
        session_id=session_id,
        frame_index=frame_idx,
        points=points_tensor,
        point_labels=points_labels_tensor,
        obj_id=obj_id,
    )
)

此方法特别适用于同类别多个个体的独立跟踪。

5.4 方法三:正负样本点联合优化分割精度

通过组合正负样本点,可排除干扰区域,实现更精细的掩码生成:

points_abs = np.array([
    [421, 155],  # 正样本:衣服区域
    [420, 202],  # 负样本:腿部(排除)
    [400, 107],  # 负样本:头部(排除)
])
labels = np.array([1, 0, 0])

points_tensor = torch.tensor(
    abs_to_rel_coords(points_abs, IMG_WIDTH, IMG_HEIGHT, "point"),
    dtype=torch.float32,
)
points_labels_tensor = torch.tensor(labels, dtype=torch.int32)

predictor.handle_request(
    request=dict(
        type="add_prompt",
        session_id=session_id,
        frame_index=frame_idx,
        points=points_tensor,
        point_labels=points_labels_tensor,
        obj_id=obj_id,
    )
)

经此调整后,模型仅分割出女孩的衣服部分,而非全身轮廓,显著提升语义准确性。


6. 总结

SAM3 凭借其强大的提示交互能力和视频感知结构,为视频目标分割提供了前所未有的灵活性与易用性。结合 CSDN 提供的 sam3 提示词引导万物分割模型 镜像,开发者可以:

  • 快速部署运行环境,免去繁琐依赖安装;
  • 通过文本、点、框等多种提示方式灵活控制分割行为;
  • 实现跨帧目标跟踪、ID 管理与动态增删;
  • 在 WebUI 或代码层自由切换,满足不同开发需求。

无论是用于智能监控、视频编辑、AR/VR 内容生成,还是科研分析,SAM3 都展现出极高的工程价值与扩展潜力。未来随着更多定制化微调方案的涌现,其在垂直领域的落地能力将进一步增强。


获取更多AI镜像

想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。

Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐