SAM3文本引导万物分割实战|基于大模型镜像快速实现视频目标分割
1. 引言:让视频分割变得简单而精准
你有没有想过,只需要输入一句话,比如“红色的汽车”或者“穿蓝衣服的小孩”,就能自动从一段视频里把对应的目标完整分割出来?这不再是科幻场景,而是今天就能实现的技术现实。
SAM3(Segment Anything Model 3)作为新一代“万物分割”模型,正在彻底改变图像和视频处理的方式。它不仅能识别你描述的物体,还能在整个视频中持续跟踪并精确分割出这个目标。更厉害的是——你不需要画框、不需要标注,只要会说话,就能操作。
本文将带你基于CSDN星图提供的sam3镜像环境,快速上手实现视频级别的目标分割与跟踪。我们将重点演示如何通过文本提示和点提示两种方式,在复杂场景下精准提取指定目标,并支持跨帧连续追踪、添加或移除目标等高级功能。
整个过程无需从零部署模型,只需启动镜像,调用接口,几分钟内即可看到效果。无论你是做智能监控、视频剪辑,还是研究目标跟踪,这套方案都能直接落地使用。
2. 镜像环境准备与Web界面快速体验
2.1 镜像核心能力一览
我们使用的sam3 提示词引导万物分割模型镜像是一个开箱即用的生产级环境,集成了以下关键组件:
- 算法基础:SAM3(Segment Anything Model 3),Meta最新发布的第三代通用分割模型
- 交互方式:支持自然语言文本输入(如 "dog", "bottle")
- 可视化界面:Gradio开发的WebUI,操作直观,适合调试和演示
- 运行环境:
- Python 3.12
- PyTorch 2.7.0 + CUDA 12.6
- 模型代码位于
/root/sam3
该镜像已经预加载了权重文件和BPE词表,省去了繁琐的依赖安装和模型下载步骤。
2.2 启动WebUI,三步完成图像分割
- 启动实例后等待10-20秒,系统会自动加载SAM3模型。
- 点击控制台右侧的“WebUI”按钮,打开交互页面。
- 上传一张图片,输入英文描述(例如
person,cat,red car),点击“开始执行分割”。
很快你就能看到画面中被准确圈出来的目标区域,每个分割结果都带有独立ID和置信度标签,点击即可查看详情。
小贴士:目前模型主要支持英文Prompt。建议使用常见名词+颜色/位置修饰,如
blue shirt,left dog,能显著提升识别准确率。
如果你想手动重启服务,可以运行以下命令:
/bin/bash /usr/local/bin/start-sam3.sh这个Web界面非常适合快速验证想法,但对于视频处理来说,我们需要更精细的控制能力——接下来就进入真正的实战环节。
3. 视频目标分割实战:从单帧到全时序跟踪
虽然WebUI方便快捷,但要实现视频级的目标跟踪与动态编辑,我们必须深入代码层,利用SAM3提供的API进行编程控制。
下面我们将一步步完成:视频拆帧 → 初始化会话 → 添加文本提示 → 跨帧传播 → 动态增删目标 → 精细调整分割区域。
3.1 环境与库导入
首先确保你的环境中已安装必要的工具包:
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, )这些库的作用分别是:
cv2:视频读取与格式转换torch:PyTorch框架支持GPU加速supervision:用于掩码可视化和边界框绘制sam3.*:核心预测器和可视化工具
3.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"未知坐标类型: {coord_type}")这两个函数将在后续频繁调用,尤其是propagate_in_video,它是实现跨帧跟踪的核心。
4. 加载模型并初始化视频会话
4.1 加载SAM3视频预测器
# 使用当前可用的GPU设备 DEVICES = [torch.cuda.current_device()] # 指定模型路径 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 )模型加载完成后,就可以开始处理视频流了。
4.2 视频预处理:拆分为图像帧
假设我们的原始视频是bedroom.mp4,需要先将其拆解为一系列有序图片:
SOURCE_VIDEO = "assets/videos/bedroom.mp4" output_dir = 'output2' os.makedirs(output_dir, exist_ok=True) # 使用ffmpeg按顺序导出每一帧 !ffmpeg -i {SOURCE_VIDEO} -q:v 2 -start_number 0 output2/%05d.jpg这样我们就得到了一个按编号排序的图片序列,便于后续逐帧访问。
4.3 读取所有视频帧用于可视化
video_frames_for_vis = glob.glob(os.path.join("output2", "*.jpg")) video_frames_for_vis.sort( key=lambda p: int(os.path.splitext(os.path.basename(p))[0]) )现在video_frames_for_vis就是一个包含所有帧路径的列表,索引即对应时间顺序。
5. 开始视频分割任务:创建会话与初始提示
5.1 初始化视频处理会话
每次处理新视频前,都需要创建一个新的会话:
response = predictor.handle_request( request=dict( type="start_session", resource_path=SOURCE_VIDEO, ) ) session_id = response["session_id"]这个session_id是后续所有操作的唯一标识。如果你发现推理结果异常,可以通过以下命令重置会话:
_ = predictor.handle_request( request=dict( type="reset_session", session_id=session_id, ) )6. 方法一:用文本提示自动分割目标
最简单的分割方式就是直接告诉模型你想找什么。
prompt_text_str = "person" # 想要分割的对象 frame_idx = 0 # 在第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"]此时模型会在第一帧中搜索所有符合“person”的人,并生成对应的掩码。
我们可以立即查看第一帧的分割效果:
plt.close("all") visualize_formatted_frame_output( frame_idx, video_frames_for_vis, outputs_list=[prepare_masks_for_visualization({frame_idx: out})], titles=["SAM3 文本提示分割结果"], figsize=(6, 4), )你会看到画面中出现了多个被标记的人形轮廓,每个都有唯一的ID编号。
7. 全程跟踪:让目标在整段视频中持续存在
有了初始分割结果,下一步就是让这些目标在整个视频中保持连贯。
# 执行全程传播 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=["SAM3 全程密集跟踪结果"], figsize=(6, 4), )你会发现,无论是走路、转身还是短暂遮挡,模型都能稳定地跟踪每个人物,ID不会错乱,边缘也很清晰。
8. 动态管理目标:移除不需要的对象
有时候我们只想保留特定个体。比如画面中有两个小孩,但我们只关心穿红衣服的那个。
这时可以按ID移除另一个:
obj_id = 1 # 要删除的目标ID 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) outputs_per_frame = prepare_masks_for_visualization(outputs_per_frame)再次可视化时,你会发现ID为1的目标已经消失,只剩下我们关心的那个主体。
9. 方法二:用点提示精准添加目标
除了文本,还可以通过点击屏幕上的某个点来指定目标位置,这种方式更适合精确定位。
下面我们尝试把刚才删掉的目标重新加回来,但这次只让它分割“衣服”部分。
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, coord_type="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, ) )提交后再次传播,你会发现ID=1的目标重新出现,而且只覆盖了衣服区域。
10. 方法三:结合正负样本点实现精细分割
如果想进一步优化分割精度,可以用正负样本点组合的方式排除干扰区域。
例如,我们希望只保留小女孩的衣服,去掉头发和脸部:
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, coord_type="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, ) )再次运行传播后,你会发现分割结果更加聚焦于衣物本身,完全避开了面部和其他无关区域。
这种交互式修正机制,使得SAM3不仅自动化程度高,还具备极强的可干预性,真正做到了“智能+可控”。
11. 总结:为什么SAM3值得你立刻尝试?
通过本次实战,你应该已经感受到SAM3在视频目标分割方面的强大能力。总结一下它的几大优势:
- 极简交互:一句英文描述就能完成目标定位,无需训练、无需标注
- 多模态提示:支持文本、点、框等多种输入方式,灵活应对不同需求
- 跨帧跟踪:能在整段视频中稳定追踪目标,ID不漂移
- 动态编辑:随时添加、删除、修正目标,满足精细化操作需求
- 一键部署:借助CSDN星图镜像,免去环境配置烦恼,开箱即用
无论你是做安防监控中的人员追踪、影视后期中的对象抠像,还是科研项目中的行为分析,这套方案都能大幅降低技术门槛,提升工作效率。
更重要的是,这一切都不需要你成为深度学习专家。只要你懂基本的Python操作,就能驾驭如此强大的AI能力。
获取更多AI镜像
想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。