
简介使用Ultralytics框架开展SAM2图像分割的开发者可在此获得完整模型权重与测试代码。资源围绕人工智能、深度学习中的图像分割场景以Meta的SAM2模型为基础支持通过Prompt提示词进行目标分割以及全图自动分割两种方式适合有一定深度学习基础、希望快速上手SAM2的算法工程师与学生。压缩包共7个文件约690.55MB其中4个pt文件为不同规格的PyTorch模型权重tiny、base、small、large可按精度与速度需求灵活选用2个py文件对应“Segment_with_Prompts.py”与“Segment_Everything.py”两套测试脚本分别演示带提示词分割与全图分割流程另含1张jpg测试图片便于直接验证效果。目前已有1265人学习下载。这份资源省去了自行下载权重与编写调用代码的步骤拿到后即可运行体验SAM2的核心能力也可作为二次开发与效果对比的基础。 先交代一个背景大约是2024年年中的时候Meta放出了SAM2的论文和权重我当时正在做一个需要从视频里持续分割某个运动目标的边缘项目第一时间就上手试了。最开始用官方仓库的代码说实话能用但工程体验一般——数据加载逻辑复杂和现有训练管线对接要写一堆胶水代码推理速度也没有真正压榨到位。后来Ultralytics把SAM2集成进框架之后整个流程清爽了很多而且能直接复用熟悉的那套API风格。这篇文章就聊聊我用Ultralytics框架跑SAM2的完整过程从安装到推理、从点提示到视频流处理、再到具体的坑和调优思路给想直接上手SAM2的人一份能照着写的参考。1. 为什么是SAM2Ultralytics这对组合先说SAM2本身。相比第一代SAMSAM2最大的变化是引入了流式记忆机制它不再把视频当作独立的帧来分割而是让模型在时序上记住前一帧的掩码和特征所以做视频目标分割时不会出现目标在某一帧突然丢失、下一帧又蹦出来的尴尬情况。这也让它在交互式分割里的表现更连贯用户点一下目标后面的帧基本都能跟上这点做视频标注工具的人会体会很深。而Ultralytics那头它做的事情并不是简单把官方权重包一层API而是把模型加载、推理、可视化、甚至微调入口都统一到了自家生态里。如果你之前用过YOLO系列检测你会发现SAM2在这里的使用方式几乎是零学习成本同样的模型加载方式同样的predict调用逻辑同样的结果对象属性访问。这种检测分割全家桶式的体验在需要把YOLO做目标检测、SAM2做精细分割串成一条流水线时价值非常大。从我实际项目的体感来说Ultralytics版本对显存的使用也更克制。官方示例里如果你想跑一个batch的预测往往需要自己处理padding和归一化但Ultralytics封装后它内部的预处理管线帮你处理了这些细节我同样的4060显卡官方实现跑视频推理偶尔爆显存切到Ultralytics框架后稳定了很多。2. 环境准备与安装第一个容易卡住的地方2.1 版本依赖和安装命令安装Ultralytics很简单但有几个版本细节我建议你注意。先用一条命令装主框架pip install -U ultralytics如果你需要GPU加速请确保本机已经有可用的CUDA环境。我这里实测的是CUDA 11.8和12.1都能正常跑torch的版本建议2.0以上太老的话某些算子会编译不过。SAM2的权重是单独的需要从Ultralytics的权重仓库下载也可以用下面的Python方式自动拉取from ultralytics import SAM model SAM(sam2_b.pt)这里有个坑不同后缀对应不同的模型规模和用途。sam2_b.pt是base版显存友好sam2_l.pt是large版精度更高但吃显存也更多。如果只是验证效果先跑base版不要一上来就上large。2.2 显存和计算平台的选择建议SAM2的backbone是Hiera这是一个视频预训练的层次视觉Transformer参数量控制得相对合理。但这不代表它对硬件没有要求。实测下来4GB显存可以跑sam2_b的单张图片推理但视频流建议batch设为18GB显存比较舒服的分界线能同时开几个进程做批量推理16GB及以上可以跑sam2_l,也能开较大的视频batch。如果是纯CPU环境我建议直接放弃实时分割的想法。SAM2的Transformer结构在CPU上的推理速度非常感人实验可以生产不现实。2.3 一个容易被忽略的问题模型权重路径很多初学者卡在最开始明明pip install成功了但加载权重时报错文件找不到。这是因为Ultralytics不会在安装时把权重文件一并下载而是在模型初始化时才去拉取。如果你所在的网络环境对GitHub或特定对象存储连接不稳定下载会失败。解决方案有两个手动从官方Release页面下载对应权重放到项目目录下然后改加载路径model SAM(weights/sam2_b.pt)设置环境变量让框架走镜像源export ULTRALYTICS_WEIGHTS_URL你所在的区域可访问的镜像地址我个人推荐第一种省心且可控重跑实验时也不会反复去联网拉文件。3. 核心API使用逻辑SAM2和YOLO的差异点在哪3.1 Predictor的两种模式Ultralytics的SAM2支持两种提示方式自动模式和提示模式。自动模式适合一次性给整张图所有目标做分割它的使用代码非常简洁model SAM(sam2_b.pt) results model(demo.jpg) for result in results: result.show()这种方式底层会自动在全图上生成一组候选点然后通过模型预测出所有潜在的物体掩码有点像是把目标检测和分割合二为一了。你要的广告牌图像分割系统这类场景如果不关心广告牌的具体位置而只需要把广告区域从背景里挖出来用这个模式就够了。提示模式则更精确适合你已经知道目标在画面中大概位置的情况。看下面例子import cv2 from ultralytics import SAM model SAM(sam2_b.pt) image cv2.imread(billboard.jpg) points [[500, 300]] # 广告牌中心点的大致坐标 labels [1] # 1表示前景 results model.predict(image, pointspoints, labelslabels)注意这里的points是嵌套的列表因为API支持同时传入多个点来提示模型——比如你想分割一只被栏杆遮挡的狗只点身体可能不够你可以同时点在狗头和狗屁股上模型会更完整地理解目标边界。多点的形式是points [[500, 300], [520, 280]] labels [1, 1]3.2 如何拿到并保存掩码结果对象result里关键的属性是masks它是一个Masks对象内部有data属性形状是(N, H, W)的numpy数组概率值。如果你想转成二值掩码保存import numpy as np masks results[0].masks.data.cpu().numpy() binary_mask (masks[0] 0.5).astype(np.uint8) * 255 cv2.imwrite(mask.png, binary_mask)如果你要叠加在原图上做可视化直接用result.plot()就能得到画好掩码的图。这个函数内部帮你处理了透明度混合还有目标的类别标签显示非常方便。4. 筛选特定目标的mask逻辑广告牌分割实战4.1 全图分割后的过滤思路如果你用自动模式跑一张街景图得到的结果往往有几十个不同目标的掩码。你只想要广告牌怎么筛我用的方案是把自动分割的结果和检测模型的输出做空间匹配。具体来说先跑一个YOLO模型检测广告牌目标的边界框再从这个边界框中取一个中心点输入给SAM2作为点提示。相当于YOLO负责找到目标在哪SAM2负责把目标边界抠得精细各取所长。完整代码大致如下from ultralytics import YOLO, SAM import numpy as np yolo YOLO(yolov8n.pt) sam SAM(sam2_b.pt) image street.jpg det_results yolo(image)[0] for box in det_results.boxes.xyxy.cpu().numpy(): x1, y1, x2, y2 box.astype(int) # 过滤掉太小和太大的框避免误检 if (x2 - x1) * (y2 - y1) 1000: continue center_point [[(x1 x2) // 2, (y1 y2) // 2]] sam_results sam.predict(image, pointscenter_point, labels[1]) # 保存当前广告牌的掩码 masks sam_results[0].masks.data.cpu().numpy() mask_img (masks[0] 0.5).astype(np.uint8) * 255 cv2.imwrite(fbillboard_mask_{x1}_{y1}.png, mask_img)这套组合在实际项目中最大的优势是YOLO对目标定位的误差不会传导给SAM2。因为SAM2本身就对提示点不敏感极点附近一两百像素的偏移对最终mask的影响不大它真正在意的是提示点在不在目标区域内。4.2 广告牌这类大目标的分割注意事项广告牌有一个特殊之处它是大面积的平面矩形在图像里往往画面占比很大且包含的文字区域纹理复杂。如果用自动模式模型有可能把广告牌上的文字、Logo单独切成一个个目标导致最后拿到的是碎块。解决办法是在生成掩码后做一次后处理对mask求连通域把面积占比小于整张图1%的碎块合并到最近的父掩码上。或者更简单直接对掩码做形态学闭运算把细小空洞填充掉import cv2 kernel cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5)) closed_mask cv2.morphologyEx(binary_mask, cv2.MORPH_CLOSE, kernel)这一步我实测对广告牌效果提升非常明显因为广告牌上经常有镂空字不闭运算的话掩码会像被啃过一样。5. 视频流中的SAM2从单帧到clip的推理策略5.1 对每一帧调用模型是最笨的方法刚拿到SAM2时很多人下意识的做法是打开视频流每一帧都调用model(frame)但这样有两个问题慢。SAM2的内部结构决定了它跑一帧的耗时要比YOLO多一个量级每帧都跑根本扛不住冗余。标题也说了SAM2的卖点是流式记忆如果逐帧都重新跑那你完全没利用到这个模型的时序记忆能力。正确的方式是用SAM2VideoPredictor这类接口Ultralytics提供或自己实现帧间记忆复用只在第一帧或关键帧上给提示后续帧让模型根据之前的隐藏状态自动传播掩码。5.2 用Ultralytics实现关键帧传播在Ultralytics中做视频SAM2分割一个可行的方法是用model.track()做目标追踪然后只在检测置信度下降到阈值时重新提示。这个方案其实非常工程化——目标被遮挡一段时间后重新出现时SAM2的记忆可能已经失效这时重新给一个点提示比让它硬猜准得多。伪代码cap cv2.VideoCapture(street_video.mp4) ret, frame cap.read() # 初始帧手动指定目标点 points [[300, 200]] labels [1] while cap.isOpened(): ret, frame cap.read() if not ret: break results sam.predict(frame, pointspoints, labelslabels) masks results[0].masks.data.cpu().numpy() # 如果当前mask面积骤减说明目标可能被遮挡或丢失 if masks[0].sum() previous_sum * 0.3: # 这里可以调用YOLO重新检测目标中心点 det yolo(frame)[0] if len(det.boxes) 0: x1, y1, x2, y2 det.boxes.xyxy[0].cpu().numpy().astype(int) points [[(x1 x2) // 2, (y1 y2) // 2]] previous_sum masks[0].sum()这套逻辑的重点是mask面积骤减这个判断条件。它本质上是一个廉价的目标丢失检测器——真正的目标不会突然缩小到原来的30%以下如果发生了一定是跟踪出了问题这时候重新触发检测是最合理的策略。5.3 视频分割的显存管理视频流的特征是图像尺寸固定但帧数很大。如果你按上面的方式逐帧循环每一帧的中间特征都会被保留下来如果模型内部没有清理机制很快会OOM。对策有两个一是限制视频输入分辨率results sam.predict(frame, imgsz1024)这样可以让内部缩放图片减少张量尺寸二是每处理完N帧后主动重置模型的内部状态model.reset_memory() # 如果有该接口Ultralytics在SAM2的封装中预留了这个状态管理逻辑实际项目中我每处理完200帧重置一次显存占用能稳定控制在安全线以下。6. 在医学图像分割场景中的使用边界的经验一直以来医学图像分割多是用UNet这类编码器-解码器结构。SAM2出来之后很多文章讨论它能不能替代UNet做病灶分割。我的实际体验是能但有前提。前提之一是它对单张切片的交互式标注效果极好。比如你有一批CT切片想快速给医生做一个标注工具让医生在几个关键切片上点几下模型自动生成其他位置的病灶掩码——这活儿SAM2是能胜任的而且比UNet类模型省去大量训练时间零样本直接跑。前提之二是如果你要的是像素级的精确边界比如肿瘤区域分割的Dice系数要求很高SAM2的效果可能反而不如针对这个任务微调过的UNet。因为SAM2的掩码偏向于自然物体的边界形状而病灶边界往往有复杂的纹理过渡和灰度渐变SAM2在没有微调的情况下会把这些过渡区域一刀切掉。所以我的建议是医学图像场景下把SAM2当作标注辅助工具而不是最终推理模型。它的核心价值在于快速让人工从繁重的逐像素手工标注中解放出来而不是替代专业的分割网络。7. 精度与速度的权衡半精度和输入尺寸的影响7.1 半精度推理有多快Ultralytics框架默认会尝试用FP16半精度推理。这一点对SAM2尤其重要因为Transformer的参数量大FP16能直接省一半显存同时推理速度提升约40%到60%。你可以显式指定results model.predict(demo.jpg, halfTrue)如果你发现结果出现诡异的噪声再用halfFalse回退试试部分老显卡的半精度支持不完善会有精度损失。7.2 输入尺寸怎么选SAM2官方训练时用的分辨率是1024x1024左右。你如果给它特别大的图比如4000x3000的广告牌实拍图内部会先缩放再推理所以显存不会爆炸但小目标的细节会在缩放中丢失。反过来如果你把图缩到512x512再跑速度会快很多但掩码边缘会出现明显锯齿。我的经验是对广告牌这类画面占比大的目标输入尺寸设1024就够对医学切片这种细节密集的图可以设到1536代价是推理时间增加。调imgsz参数权衡一下就行。8. 我踩过的三个坑和最终的建议第一个坑是results里masks对象为空指针。原因是某些输入图片某些通道值异常比如全黑或全白图模型没有生成任何有效目标。排查这种问题不要急着看代码先用cv2.imwrite把前处理后的图像存出来肉眼检查一下。第二个坑是自动模式下重复掩码特别多。同一个物体有时会被模型切成好几块每块都有一个掩码看起来非常乱。解决办法是给重叠掩码加NMS逻辑计算两两IoU超过0.8的只保留面积大的那个。Ultralytics的结果对象里不直接提供这个函数但用skimage或自己写几行就能搞定。第三个坑是模型在第一次推理时会自动下载或者初始化一些缓存文件如果你在Docker容器里跑且没有写权限会直接报错。建议在镜像里预先执行一次推理把缓存打好或者设置环境变量指定缓存目录到可写路径。从最终效果看SAM2Ultralytics这套方案目前最适合的定位是快速原型验证和交互式标注工具。如果你要做的任务对边界精细度要求不高、又需要快速部署直接用它如果你要做的是高精度的垂直领域分割那拿它的分割结果做预标注再用少量人工修正喂给专用模型微调是性价比最高的路径。我在实际的广告牌分割和视频标注项目中用的就是后一种方法稳定性和效率都能拉到及格线以上。本文还有配套的精品资源点击获取