Ultralytics集成SAM2图像分割实战:从安装到部署全流程
简介配套《Segment Anything Model 2使用 Ultralytics 框架进行 SAM2 图像分割》一文的完整资源包面向深度学习与图像分割方向的开发者和学习者演示 Ultralytics 框架下 SAM2 的典型用法可应用于目标提取、背景分离、交互式标注等场景也适合作为课程设计与项目实验的动手素材。包内共 7 个文件包含 4 个不同规模tiny/base/small/large的 PyTorch 权重文件pt、2 个 Python 脚本和 1 张测试图片jpg压缩包约 690.55MB。两个脚本分别覆盖“分割一切”与“按提示词分割”两种主流调用方式测试图片用于快速验证输出效果多个档位权重便于按设备算力灵活选用。目前已有 1265 人学习下载。借助这套资源读者可直接加载模型权重运行脚本免去单独寻找权重、编写推理代码的麻烦并能对照脚本理解 SAM2 提示词机制与各参数作用为后续在 Ultralytics 体系内做二次开发和模型适配节省大量时间。1. 当SAM2遇上Ultralytics图像分割不再“高门槛”做CV的同学应该都有体会图像分割这个方向模型不少但真正能用得顺手的不多。早些年大家还在用U-Net源码到处找、预处理自己写、训练要调半天的lr和loss权重跑个推理还要自己拼接重叠patch费时费力。后来SAM一出来提示分割的思路确实让人眼前一亮但说实话部署起来还是有点麻烦——环境依赖重、模型格式特殊、跟现有检测管线打通又得自己写胶水代码。我算是比较早就开始用Ultralytics那套框架的人从YOLOv5一路用到YOLOv8、YOLO11说实话对这家的工程化能力挺服气的。所以当Ultralytics宣布把SAM2集成进自家生态的时候我是真香了。安装一个包、调一个接口就能用上Meta的SAM2模型而且能和YOLO检测无缝衔接这解决了我实际项目里一个很头疼的问题检测框有了但我还想要像素级的轮廓怎么办这篇我主要结合自己这段时间用Ultralytics跑SAM2的实战经验聊聊从环境搭建到推理部署的完整流程以及我在广告牌检测、图像分割落地过程中踩过的一些坑。不管你是刚接触图像分割的新手还是想把手头检测项目升级成分割方案的老手这篇文章应该都能给你一些参考。2. SAM2到底是什么为什么值得花时间折腾2.1 从SAM到SAM2不止是换了个版本号SAMSegment Anything Model是Meta在2023年提出来的分割基础模型它的核心能力是“提示分割”——你给它一个点、一个框或者一段文本它就能把对应的物体轮廓切出来。那个SA-1B数据集1100万张图、超过10亿个掩码让SAM学会了很强的泛化能力很多没见过的东西也能分得不错。SAM2是在2024年推出的第二代最大的变化是支持了视频分割。它把图像和视频统一到了一个框架下用了一个叫流式记忆streaming memory的机制让模型能跨帧保持目标的身份一致性。换句话说视频里那一帧你点了个人后面的帧它能一路跟着分割下去不会跟丢。但对我们做工程的人来说SAM2更实在的提升是这些模型的骨干网络换了推理速度更快显存占用比第一代更友好分割质量在边缘细节上更好尤其是细长物体和小物体那个“毛边”现象改善了不少提示方式更加灵活支持稀疏和稠密两种提示的组合输入我在实际测下来SAM2在广告牌这类规则矩形物体上得分很准在医学图像分割这类需要精细边界的场景下效果也比之前用U-Net那套稳定得多。当然这也取决于你有没有针对自己的数据做后处理优化。2.2 为什么是Ultralytics而不是直接用Meta官方仓库这个问题我被人问过好多次。Meta官方也开源了SAM2的代码理论上你按照README去装依赖、下载权重也能跑起来。但如果你做的是实际项目不是学术复现就会发现官方仓库有几个挺难受的地方第一依赖管理比较繁琐。官方库要自己创建conda环境、装对应版本的torch和tensorrt如果你机器上同时有别的深度学习项目环境之间很容易打架。第二模型格式和推理接口没有统一。官方给的权重是.pt和.torchscript格式你想转成ONNX、TensorRT或者想部署到服务端得自己写转换脚本这中间各种算子兼容问题会耗掉你大量时间。第三缺少跟检测模型的联动。实际项目里很少是纯分割需求往往是先检测再分割或者检测分割同时做。Ultralytics框架里YOLO系列本身就是一块招牌SAM2整合进去之后检测和分割在一个环境、一个API下就能搞定不需要在两个框架之间倒数据。我用下来最直观的感受是Ultralytics把很多工程上的“脏活累活”都提前做掉了。比如它会自动处理图像预处理、后处理、可视化、导出格式你只需要关心你的业务逻辑就行。对于想快速验证分割方案或者需要把分割能力集成到现有系统里的开发者来说这种开箱即用的体验太重要了。3. 环境准备与安装半小时跑通第一个SAM2推理3.1 环境要求和依赖清单先说结论Ultralytics对SAM2的支持是从8.3.0版本开始的所以装的时候务必保证版本够新。我实测下来的推荐环境如下组件推荐版本备注Python3.9 ~ 3.113.10最稳3.12有些依赖还没跟上PyTorch 2.0建议2.1以上带CUDA支持CUDA11.8 或 12.1看你的显卡驱动版本ultralytics 8.3.0旧版没有SAM2的接口显存 8GB跑sam2_b最低要求16GB更舒服基本没有额外的硬性要求不像某些模型非要特定的系统和编译环境。Windows、Linux、Mac都能跑不过如果你要用GPU加速还是建议在Linux服务器上跑Windows上NVIDIA的驱动和容器兼容性虽然现在好了很多但偶尔还是有些小毛病。3.2 安装过程实录安装其实就一条命令的事儿但有几个细节值得注意pip install ultralytics如果你之前装过老版本先升级再装pip install -U ultralytics这里有个坑当你以pip install ultralytics安装的包会和segment-anything产生命名冲突。Ultralytics内部对SAM2的支持是通过动态加载的方式实现的它会用到一个叫做sam2的Python包所以你机器上如果已经装了Meta官方的segment-anything建议先卸载掉否则import的时候会有奇怪的问题。pip uninstall segment-anything -y装完之后建议验证一下版本import ultralytics ultralytics.checks()如果你看到类似Ultralytics 8.3.x Python-3.10.x torch-2.1.x CUDA:0 (Tesla T4, 15360MiB)的输出就说明环境没问题了。3.3 权重文件的选择与下载Ultralytics框架会自动帮你下载权重文件但了解一下有哪些可选的模型选择权在自己手里会更好。目前Ultralytics支持三个SAM2变体模型参数量适合场景显存需求sam2_b80M左右快速推理、移动端或边缘设备8GBsam2_s约50M追求极致的速度8GBsam2_l300M级别最高精度服务端部署16GB以上sam2_t最小版本特殊场景速度优先6GB我第一次跑的时候自动下载的是sam2_b.pt当时还愣了一下因为和Meta官方名字不太一样。后来看了源码才知道Ultralytics内部把官方的sam2_hiera_base、sam2_hiera_small这些名字统一映射成了sam2_b、sam2_s这类简洁命名方便记忆。对应的精度差别不算特别大base在COCO类的通用目标上已经表现得很好了。4. SAM2推理实操从单张图片到批量处理4.1 基础推理最简单的三个场景安装完之后就可以跑推理了。先来一个最简单的例子加载模型并对单张图片做自动掩码生成from ultralytics import SAM # 加载模型会自动下载sam2_b.pt model SAM(sam2_b.pt) # 对图片进行全图分割 results model(bus.jpg) # 查看结果 for result in results: result.show() # 显示带掩码的图片 result.save(output.jpg) # 保存结果这是最无脑的用法模型会自动生成全图所有物体的掩码。但说实话这种方式在工程里用处有限因为很多时候你并不需要分割所有东西只需要分割你关心的目标。“全图分割”的算力开销也大一张图可能要跑好几秒钟对于实时性要求高的场景不太现实。更常用的是“提示分割”也就是你给模型一个提示它只分割对应的东西。Ultralytics API支持两种提示方式点提示和框提示。from ultralytics import SAM model SAM(sam2_b.pt) # 框提示告诉模型我只要这个框里面的物体 results model(bus.jpg, bboxes[100, 100, 400, 400]) # 点提示告诉模型这个点所在的物体是我要的 results model(bus.jpg, points[200, 200], labels[1]) # 同时用多个框 results model(bus.jpg, bboxes[[100, 100, 400, 400], [500, 200, 700, 500]])这里要注意坐标格式不管是bboxes还是points都是相对于原图的绝对像素坐标不是归一化坐标。我第一次用的时候没注意传了归一化坐标结果分割出来的东西完全不对排查了半天才发现是这个原因。4.2 结合YOLO检测SAM2YOLO的黄金搭档在实际项目里我最常用的是“YOLO检测SAM2分割”的组合。原理很简单先用YOLO跑一遍检测拿到目标框然后把框作为提示喂给SAM2让SAM2把目标的精细轮廓分割出来。这样既利用了YOLO的速度和检测精度又能拿到SAM2的像素级分割结果。from ultralytics import YOLO, SAM # 1. 用YOLO检测目标 det_model YOLO(yolo11n.pt) det_results det_model(advertising_board.jpg, conf0.25) # 2. 提取检测框 boxes [] for r in det_results: for box in r.boxes: x1, y1, x2, y2 box.xyxy[0].tolist() boxes.append([int(x1), int(y1), int(x2), int(y2)]) # 3. 用检测框作为提示交给SAM2做精细分割 seg_model SAM(sam2_b.pt) seg_results seg_model(advertising_board.jpg, bboxesboxes)这个组合我在实际项目中验证过相比直接用YOLO的分割模型YOLO11也有分割版本SAM2的边缘精细度要好很多。特别是广告牌这种上面有大量文字、图案的目标YOLO的分割掩码经常会把文字区域和背景混在一起边缘坑坑洼洼换SAM2之后文字区域和牌体边界分得清清楚楚。有一点需要提醒YOLO检测出来的框之间可能有重叠区域而SAM2在处理多个框提示时如果两个框重叠较多可能会把同一个目标分割两次。这时候要根据你的业务场景要么在YOLO检测阶段把NMS阈值调低一点要么在拿到分割结果后做一次重叠掩码的合并处理。4.3 批量推理与结果导出项目落地的时候不太可能一张一张图来跑。我一般是把图片路径放在一个文件夹里然后写一个循环做批量处理。Ultralytics的API也支持直接传文件夹路径它会自动遍历目录下所有支持的图片格式from ultralytics import SAM model SAM(sam2_b.pt) results model(path/to/images/, bboxes[100, 100, 400, 400]) # 批量保存结果 for i, r in enumerate(results): r.save(fresults/{i}_mask.jpg)导出掩码的时候如果你是要做后续分析或者训练建议导出成PNG格式的掩码图而不是直接保存带标注的可视化图import numpy as np # 拿到二进制掩码 result results[0] masks result.masks.data.cpu().numpy() # shape: [num_masks, H, W] # 保存为二值掩码 for idx, mask in enumerate(masks): mask_img (mask * 255).astype(np.uint8) cv2.imwrite(fmask_{idx}.png, mask_img)这里还有个经验result.masks.data默认是Tensor类型要记得转成numpy再处理不然很多图像处理库会报类型错误。5. 性能调优与常见问题排查5.1 推理速度优化从6秒到1.5秒我第一次用SAM2跑单张图片时处理时间大概6秒当时还以为是模型太重了。后来排查下来发现大部分时间都耗在了“全图分割”上——SAM2在没有提示的情况下会对整张图所有可能的目标做分割这是最耗时的模式。换成框提示之后单张图的速度降到了2秒左右。在此基础上我又做了几个优化最终把单张图的推理时间压到了1.5秒以内半精度推理把模型转成FP16显存占用减半速度提升明显model SAM(sam2_b.pt, fp16True)设置batch大小如果是一次处理多张图适当增大batch可以利用GPU并行计算results model(images_dir/, batch4)关闭可视化如果不需要看结果图关闭可视化代码避免CPU和GPU之间频繁拷贝数据如果是需要部署到生产环境还可以把模型导出成TensorRT格式在NVIDIA显卡上能进一步提速。Ultralytics的export接口支持直接导出model SAM(sam2_b.pt) model.export(formatengine, imgsz1024)导出的时候要注意TensorRT的engine格式和硬件绑定换一张显卡就得重新导出一次这是个容易踩的坑。5.2 显存不足的解决办法SAM2的显存占用比第一代SAM优化了但大图还是容易OOM。我在处理高分辨率航拍图的时候遇到过好几次显存溢出的报错CUDA out of memory。解决方案有这么几个首推分块推理。把大图切成若干小块每块单独过SAM2再把结果拼回原图尺寸。切块的时候建议留一点重叠区域比如19,20像素拼接的时候取边界平均避免分割边缘出现明显的接缝。如果是单图推理最直接的办法是降低输入分辨率。Ultralytics的imgsz参数可以控制模型接收的输入尺寸比如原来用1024降到768或640显存占用会显著下降。results model(large_image.jpg, imgsz768)不过要注意分辨率降太多会影响小目标的分割精度。如果目标本来就很小还是建议用分块方案不要盲目降分辨率。5.3 分割效果不理想的排查思路如果你发现SAM2分割出来的效果不对先别急着换模型按下面这个顺序排查一下现象可能原因解决方案多框提示时漏掉部分目标框太小没有完全包住目标在YOLO检测阶段扩大框的范围比如向外扩10%分割掩码有空洞目标本身有透明区域或复杂纹理对掩码做形态学闭运算填上小空洞点提示不准确点的位置落在了目标边缘手动或用算法把点向目标中心偏移分割结果错位坐标体系没搞对确认输入坐标是原图坐标而非resize后的坐标轴上有个小细节我特别想说SAM2对提示框的大小比较敏感。如果框紧紧贴着目标边界分割结果往往不理想。我通常在YOLO检测框基础上向外扩展一定比例效果会好很多。这个比例我一般取框宽高的5%-10%你可以根据实际情况调整。# 扩展检测框给SAM2留出上下文空间 x1 max(0, int(x1 - 0.05 * (x2 - x1))) y1 max(0, int(y1 - 0.05 * (y2 - y1))) x2 min(W, int(x2 0.05 * (x2 - x1))) y2 min(H, int(y2 0.05 * (y2 - y1)))6. 实际项目中的应用广告牌精细分割与医学图像分割6.1 广告牌图像分割系统的实现思路我在两个月前接到一个项目需求是对城市街景里的广告牌做像素级的轮廓提取用于后续的广告内容分析和违规检测。如果按照传统的做法可能要从头训练一个分割模型标注数据量就是个巨大的坑。但用SAM2YOLO的组合整个流程就变得非常简单。我的实现思路是这样的先搜集一批街景图片用YOLO训练或直接用一个在公开数据集上预训练好的检测模型把广告牌的位置框出来。然后把检测框传给SAM2做分割得到广告牌的像素级掩码。最后对掩码做透视变换矫正得到一个近乎正面的广告牌矩形区域方便后续的OCR文字识别和内容审核。整个流程跑下来分割的准确率远超预期。在广告牌边缘有灯箱、支架、绿化遮挡等复杂情况下SAM2依然能切出相当干净的轮廓。和传统语义分割模型对不同广告牌泛化能力不足的缺点相比SAM2几乎不需要额外训练就能适应各种风格、颜色、尺寸的广告牌。这套方案里有个小技巧值得分享对SAM2生成的多通道掩码按照面积大小排序只保留面积最大的那个掩码作为最终结果。因为广告牌检测框内可能包含背景区域SAM2有可能会分割出多块东西但面积最大的那块通常就是广告牌主体。# 按面积排序保留最大掩码 masks result.masks.data.cpu().numpy() # [num_masks, H, W] areas masks.sum(axis(1, 2)) largest_idx areas.argmax() final_mask masks[largest_idx]6.2 医学图像分割场景的适配经验另一个让我印象深刻的场景是医学图像分割。有同学拿SAM2来做CT影像中器官区域的自动勾画效果比传统的U-Net方案要好不少。传统的U-Net需要大量标注数据来训练而医学影像的标注成本极高很多医院根本拿不出足够的训练数据。SAM2的零样本泛化能力在这里就有了天然优势。在实际应用中需要注意医学图像通常是灰度图而Ultralytics的输入接口默认走的是RGB三通道RGB三通道。解决办法很简单——把灰度图手动转换成一个三通道图三个通道值一样就行。import cv2 import numpy as np # 读取灰度图 gray cv2.imread(ct_slice.png, cv2.IMREAD_GRAYSCALE) # 转成三通道 rgb cv2.cvtColor(gray, cv2.COLOR_GRAY2RGB) # 用SAM2分割 results model(rgb, bboxes[[50, 50, 300, 300]])另外医学图像通常体素值范围和自然图像差异较大比如CT的HU值直接把原始数值喂给SAM2效果会打折扣。建议先做一个简单的预处理把数值范围压缩到0-255之间通常是做窗口化操作只保留感兴趣组织的灰度范围。6.3 和U-Net等传统分割方案的效果对比做这个对比是因为经常被人问到“SAM2能不能取代U-Net”之类的话题。我把同一组数据分别用SAM2和U-Net跑了一遍简单说说我的感受维度SAM2U-Net零样本能力强不需要微调就能分割弱需要大量数据训练边界精细度高细节保留好中等通常需要CRF后处理推理速度偏慢特别是全图分割模式快轻量级网络可控制性灵活支持点、框、文本提示固定输入输出不可交互训练成本基本不需要训练需要标注数据 训练时间说实话它们不是替代关系而是适用场景不同。如果你的应用场景目标类别固定、环境可控比如工业质检中只要检测某一种特定外观的工件U-Net这种轻量级模型可能更合适——推理快、部署简单、误报可控。但如果你想做一个通用性强的分割系统比如街景中的任意物体分割、医学图像中多种器官的识别SAM2的泛化能力和灵活性绝对值得选。7. 最后的经验把SAM2用好关键在引导最后分享一点我的个人体会关于SAM2这类基础分割模型的正确使用姿势。很多同学刚上手的时候喜欢直接丢一张图进去等着它把所有东西都分出来。这种用法不是说不行而是浪费了SAM2真正的能力。做好图像分割的关键不在于模型本身有多强而在于你给模型的“提示”是什么。一个精准的检测框、一个落在目标核心的点甚至一个描述性的文本提示都能让分割结果天差地别。与其在各种后处理技巧上死磕不如多花时间思考怎么生成高质量的提示。我后来的很多项目里都会把提示生成当做一个独立的模块来设计。比如用YOLO来生成“框提示”用目标中心点来生成“点提示”甚至用一些简单的启发式规则自动构造提示让SAM2更容易理解我的意图。这个思路我建议你也试试。如果你正在纠结怎么把现有检测项目升级成分割方案或者被图像分割的标注数据问题卡住了我的建议很简单先别急着训练花一天时间把Ultralytics的SAM2跑通在你的业务数据上看看效果再决定下一步怎么走。多数情况下你已经不需要从零训练一个分割模型了。本文还有配套的精品资源点击获取