ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

基于SAM和多相细化的橄榄树卫星图像分割实践

基于SAM和多相细化的橄榄树卫星图像分割实践

拿到“基于SAM和多相细化的橄榄树卫星图像分割”这个项目标题时,我第一反应是:这类活儿绝不是把开源的SAM模型下载下来,对着卫星图跑一遍就交差。橄榄树冠在0.3米分辨率的遥感影像上往往只有几十个像素,树冠与树冠之间粘连严重,边缘又被阴影和邻近植被吞掉,直接推理出来的掩膜经常是一团糊。为了让分割结果真正能用起来(清点棵树、估算冠幅、判断长势),我围绕SAM设计了一套从“全局粗分割”到“目标级细化”再到“边界精修与多时相遇判”的多相细化流程。这篇文章把整套流程拆开讲,从数据准备、模型适配到阶段细化、指标评估,每一步都写清楚为什么这么做,以及我实际踩过哪些坑。

1. 项目定位:橄榄树树冠分割到底在解决什么问题

1.1 为什么单独给橄榄树做分割

很多人会问:图像分割不是有现成模型吗,搞个通用语义分割不就行了?问题在于橄榄树分割不是一个“分类”问题,而是一个“定位+计数+形态恢复”问题。果园管理里,农户和农技人员真正想要的是:这一片地里到底有多少棵橄榄树、每棵树的冠幅多大、有没有缺苗、有没有长势异常。如果只是把影像像素分成“树”和“非树”,像素级的IoU再高,也没办法回答“多少棵”这个问题。

另外橄榄树的树冠形态特殊。它不像农田里的玉米、小麦那样成片分布,也不像林地里的树木那样密集交错,而是呈现“单株+均匀行距”的种植模式。这种模式意味着,分割任务的目标是输出一个个独立的树冠实例,而不是一张模糊的类别图。这就把任务从语义分割推到了实例分割的范畴,而在遥感尺度上做实例分割,正是SAM这类模型的弱项。

还有一层现实因素:橄榄树的经济价值高,果园通常分布在干旱、半干旱区域,地表背景复杂,裸土、石头、杂草、低矮灌木都会混进来。背景的光谱不确定性比普通耕地大得多,模型很容易把背景里的圆形地物误认为树冠。这些都会迫使你在模型之外做很多“工程化”的补救,也就是后面要讲的多相细化。

1.2 橄榄树在卫星影像上的真实样子

我先说一个直观的数据。假设你拿到的是0.3米分辨率的影像,一棵成年的橄榄树冠幅大约3米,换算下来也就是10×10像素左右;如果是新栽的小树,冠幅可能只有1.5米,也就是5×5像素。在这样一个尺度上,树冠基本上就是一个带纹理的小圆点,内部还可能有枝叶间隙造成的暗斑,边界处还有阴影。

我实际看数据时的感受是:树冠内部并不是均匀的绿色,中间会有一块暗区,边缘不圆滑,且很多树的阴影方向和树冠连线方向完全一致。这意味着,如果直接用一个简单的阈值或颜色特征去抠树冠,会把阴影也算进去;如果用一个矩形框去包住树冠,又会把邻近的另一棵树包进来。

还有地势问题。橄榄园往往建在缓坡上,太阳高度角不同,同一棵树在不同影像、不同季节里的阴影长度完全不同。这也解释了为什么单一时相的分割结果总是不稳定——有时候阴影把两棵树连成一片,有时候又给树冠边缘“抹黑”了一层。这些信号在裸眼上看很轻微,但在像素级分割时会被模型放大。

1.3 从单阶段模型到多相细化:我的整体框架

我最初也试过直接端到端方式:把影像切块,喂给SAM让它生成所有掩膜,然后过滤出橄榄树。结果就八个字:漏检严重,边界稀碎。SAM在自然图像上表现出色,但在遥感小目标场景里,它对“一堆小圆点”并不敏感。

所以我改成了多相细化,不指望一个模型一步到位,核心思想是“由粗到精、逐级逼近”。整体流程是这样的:

  • 第一相:粗分割。用检测器或SAM自动掩码生成器,找出所有可能是橄榄树冠的候选区域,这一步允许有误检,但要求召回率高。
  • 第二相:目标级重分割。把每个候选区域单独裁剪出来,放大到足够分辨率,再配合SAM的框提示或点提示,重新分割出属于该目标的掩膜。
  • 第三相:边界精修。对目标级掩膜做形态学处理、边缘约束,把阴影吞掉的边界补回来,把溢出的部分削掉。
  • 第四相:多时相遇判。引入不同物候期的影像,利用橄榄树“常绿、时序变化平缓”的特征,排除那些被误检的落叶树、草灌和作物。
  • 第五相:质检与输出。对彼此重叠的掩膜合并仲裁,对过大过小的对象做规则过滤,最后转成矢量。

这个框架里,SAM不是主角,而是阶段里的一个关键工具。真正决定精度的,是你怎么把“一棵树”从“一群树”里拆出来,以及怎么用多时相信息去做最后确认。

2. 数据准备:最琐碎、但最值钱的一步

2.1 影像选型与波段组合

分割模型的性能上限,很大程度由输入影像决定。做橄榄树冠分割,我建议至少拿到0.5米分辨率的光学影像,最好是0.3米左右。0.5米以下,一棵树只剩四五个像素,任何模型都很难还原树冠形态;等到了0.3米,树冠内部纹理、边缘轮廓才开始清晰。

我这次用的是某商业高分影像,包含红、绿、蓝和近红外四个波段。近红外波段非常关键,因为树冠的绿色植被在近红外上反射率很高,与裸土、阴影的差异比可见光波段更明显。有了近红外,我顺手就计算了NDVI,作为第四相筛选的输入特征。

这里有个实操建议:不要只喂原始RGB波段。可以把NDVI作为一个额外通道拼进输入,甚至可以把一个时相的NDVI作为先验特征输入到候选筛选阶段。NDVI对“是不是活植被”非常敏感,但单纯靠NDVI分不出“橄榄树”和“别的树”,所以它只用于排除,不用于定位。

2.2 标注策略:从点到掩膜

训练数据要标注的是“树冠实例掩膜”,而不是只给一个点或者一个框。点标注在目标检测里够用,但在分割任务里,如果没有像素级边界的监督,最后细化阶段就会缺少参照。

标注过程里最难受的是两块:粘连树冠怎么标,阴影覆盖的树冠怎么标。我的办法是:先用SAM自动跑一遍初稿,人工在初稿基础上修正。SAM生成的掩膜对于“大致是树”的对象往往还不错,人工只需要处理粘连处用切割线分开、把阴影误并进来的部分擦掉。

因为SAM初稿能省下大量描边工作,一个熟练的人在0.3米影像上标一颗树大概只需要一两秒。我们做了2600棵标注树,覆盖了不同树龄、不同光照条件的果园块,最终把数据按地块划分成训练、验证、测试三组。这里特别提醒一句:一定要按地块划分,不能随机切块划分。同一块地里相邻树冠的特征高度相似,随机划分会带来严重的“数据泄漏”,测试集指标会虚高得离谱。

2.3 图像切块与数据增强

卫星影像动辄几万×几万像素,不可能整张喂给SAM。我的切块尺寸是1024×1024,训练阶段用512×512的小块来增强数据。切块时必须带overlap,比如128像素,否则树冠被切在边缘时几乎无法恢复完整形状。

数据增强我做得比较克制:水平/垂直翻转、90度旋转、随机亮度对比度变化、轻度模糊。为什么克制?因为遥感影像有真实的物理规律,你不能像自然图像那样随便加颜色抖动。橄榄树在正射影像上的颜色、阴影方向是相对稳定的,增强过头会让模型学到“假阴影”,反而干扰边界判断。

还有一个小技巧:对树冠比较稀疏的地块,可以做一些“复制粘贴”增强。把标注好的树冠区域裁下来,粘贴到无树区域,同时生成对应的掩膜。这个操作能有效缓解训练样本里“树冠占比少”造成的前景-背景类不平衡问题。

3. SAM适配与分割实现:把通用模型拉回遥感赛道

3.1 SAM在遥感小目标上的短板

先说结论:SAM在自然图像上很强,但直接用在遥感小目标分割上,效果会明显打折。原因有三。

第一,SAM的预训练数据里,遥感影像占比很低,像橄榄树这样“小而圆、排列规则、背景单调”的目标,跟它熟悉的“猫、狗、人、汽车”差得很远。第二,SAM默认的推理方式是对较大的图像区域生成掩膜,当画面里密密麻麻排着上百棵小树时,它会倾向于输出连片掩膜而不是一个个独立实例。第三,SAM的提示机制(点、框)对中等尺度物体最友好,但橄榄树冠在整张图里太小,一个“点提示”落下去,它可能把周围一整片暗色区域全当成树冠。

我更愿意把SAM理解为一把“手术刀”,而不是“自动切割机”。它单挑一只目标时很可靠,但没人帮它把每个目标框出来、放大,它就不知道往哪儿下刀。

3.2 用切块+提示把SAM逼到每个树冠上

我的做法是先用一个目标检测器来生成候选框,再用候选框作为SAM的提示。检测器我用的是轻量化的YOLO版本,输入512×512的切块,负责输出橄榄树冠的矩形框。

为什么中间还要插一个检测器?因为直接在整张1024×1024图上让SAM生成掩膜,它会漏掉很多小目标;反过来,让SAM只处理一个框内的小区域,它才有足够空间分辨率去分辨树冠边界。检测器提供“在哪里”,SAM负责“边界长什么样”,两个角色分离,各干各擅长的事。

实际操作里,我对每个候选框做一步“放大裁剪”:把框向外扩30%的边距,再把这块区域resize到256×256左右,作为SAM的输入。这样做的目的是让树冠在SAM的输入里占据更大的有效像素占比。实验下来,对比不放大直接分割,放大后的掩膜边界IoU平均能提升4到6个百分点。

3.3 框提示和点提示哪个更好

我同时试过点提示和框提示。点提示需要先算出树冠中心点,但树冠中心往往被枝叶间隙分成两半,点落进去后SAM可能只分割出半棵树;框提示则直接给出一个空间约束,SAM在框内找目标,不容易跑飞。

如果检测器输出坐标精度不够,框稍微偏一点,SAM也能容忍,一般容忍尺度在框自身尺寸的10%到20%。根据我的测试,框提示比点提示的稳定性高很多,在粘连场景下,漏分割率能降低一半以上。

当然,框提示也不完美。如果两个树冠挨得太近,检测器给出的框会同时包住两棵树,SAM在这一个框里会尝试输出两个掩膜。这种情况的处理方式我放在后面的细化阶段讲。

4. 多相细化:从粗糙掩膜到精准树冠的打磨过程

4.1 第一相:粗获取,宁可多检,不可漏

粗分割阶段的目标只有一个:召回率尽量高。我对检测器输出的候选用较低置信度阈值,比如0.25,就是把那些“像又不太像”的对象全部保留下来。同时,我会对SAM的自动掩码生成器结果做关联:如果检测框和某个自动掩膜有超过一半的交集,就把这个自动掩膜也补充进候选池。

这一步的代价是会产生大量误检。比如一块圆形的裸土、一丛枯草,都可能被当成树冠。没关系,到了第四相,多时相信息会把它们踢掉。粗获取阶段最忌讳的是“过度清洗”,你想象的NMS、面积过滤、置信度卡高,都会把真目标提前干掉。我的经验是:粗阶段多做加法,细阶段再做减法。

4.2 第二相:目标级SAM重分割

拿到候选框后,我把每个框单独裁剪、放大,再做SAM分割。这个阶段我用的提示是“框+掩膜”二段式:第一步,在框提示下让SAM输出一个完整掩膜;第二步,把这个掩膜反转为新的掩膜提示,再次输入SAM,让它“看一眼刚才的结果再修正一次”。

第二次迭代修正的意义,是让SAM基于一个更接近真实树冠形状的先验,重新判断边界。第一次它容易把阴影和树冠混在一起,第二次它看到“这是个大致圆形的区域”,就会更倾向于输出一个完整、闭合的树冠。实际操作中,二次修正可以明显减少边界断裂和孔洞,但不需要做三次以上,收益会递减。

在这个阶段还有一个关键参数:掩膜面积阈值。树冠面积在0.3米影像上通常介于15到120像素之间。小于10像素的掩膜大概率是噪声,大于200像素的基本是把多棵树连在一起了。我不直接删除这些异常值,而是打上“待审核”标记,留给后续阶段处理。

4.3 第三相:边界精修与形态学处理

SAM输出的二值掩膜虽然比粗分割干净,但仍然有锯齿、毛刺,还有树下阴影带造成的凹陷。我用三招处理。

第一招是形态学操作:先做一次3×3的闭运算,把树冠内部小孔填掉;再做一次开运算,把边界外的孤立杂点去掉。对于橄榄树这种近圆形目标,核大小不要超过3,否则会吞掉真实边界细节。

第二招是边缘对齐:我用Canny算子提取原始影像中的边缘,然后用边缘图去约束掩膜边界。具体做法很直接:对形态学处理后的掩膜边界点,逐个检查它附近(3像素内)是否有Canny边缘;如果某个边界段附近始终没有影像边缘,说明这里可能是模型臆造出来的边界,就把它削掉或拉直。

第三招是条件随机场(CRF)微调。我把初始掩膜当作软标签,结合像素颜色和位置做一步稠密平滑。但这一步要非常小心,CRF在自然图像上效果好,在遥感图上容易把邻近的两棵树的边界“互融”。我的经验是CRF只用于单棵树的抠图,绝不能在整张大图上做。

4.4 第四相:多时相遇判与去伪

现在轮到“多相”的第二个含义了:多时相。

橄榄树是常绿树,全年NDVI相对稳定,而它周围的杂草、小麦、落叶果树,在不同季节的NDVI波动非常剧烈。我拿了三个时期的影像:春季、夏季、秋季。对每个候选树冠位置,分别计算对应时期影像上的NDVI均值,然后看这条时间序列的形态。

橄榄树的时间序列是一条平缓的线;一年生作物是明显的“升-降”曲线;裸土和枯草则全年都很低。我把这个特征输入一个简单的规则分类器或轻量分类模型,就能把大量误检过滤掉。实测下来,仅这一步就能把误检率从30%降到10%以下。

多时相还有一个隐藏价值:它能纠正“阴影造成的漏检”。一棵树在夏季影像上可能被长阴影盖住一半,但在春秋影像上阴影方向不同,树冠的另一侧能看到。如果某个候选在三个时相中至少两个时相里都有较强树冠响应,我就判定它确实存在,并选择NDVI最接近典型常绿值的那一期作为分割主图。

4.5 第五相:质检与输出

最后一相是规则化的质检与合并。流程是这样的:先对所有掩膜做重叠仲裁。如果两个掩膜的重叠面积超过较小者的40%,说明这两处其实可能是同一棵树被重复分割了,我保留置信度较高或边界更圆润的一个。然后检查树冠面积是否落在15到120像素区间内,超范围的进入人工复核列表。

还需要做一次“行距一致性检查”。橄榄树是规整种植的,大致应该落在一条直线上。我会对附近若干个树冠中心点做直线拟合,如果某个目标严重偏离拟合直线,同时它的形状又不是规整圆形,就把它标记为误检。这个规则很“土”,但非常有效,因为它利用了橄榄园特有的农艺结构,而不是单纯的视觉特征。

最终输出包括:树冠掩膜栅格、树冠中心点矢量、每棵树的面积和长宽比统计。栅格用于画图和计算覆盖率,矢量用于后续接GIS和农艺管理平台。

5. 训练细节与评估指标:让每一步都可以量化

5.1 损失函数与微调策略

在这个项目里,需要训练的部分主要是候选检测器和多时相分类器,以及可选的SAM轻量化微调。

检测器我用的是YOLO系列,损失是它自带的框回归+分类损失,这里不赘述。多时相分类器我用一个结构非常简单的小网络,输入三个时相的NDVI序列和树冠区域纹理特征,输出“是橄榄树/不是橄榄树”,用交叉熵损失就可以,因为样本量不大,太复杂的网络容易过拟合。

如果要对SAM做微调,我的建议是冻结图像编码器,只微调掩膜解码器和提示编码器。图像编码器是SAM最吃显存的部分,全部微调成本高,而且遥感影像与自然影像在底层特征上仍有共通性,没必要全部重训。微调时用Dice损失加交叉熵损失的组合,权重大约7:3。Dice损失对前景像素少的情况更友好,交叉熵保证梯度稳定。

如果你连微调都不想碰,也可以完全不训练SAM,只把它当推理工具用。我前几轮实验就是纯推理,靠后处理把精度拉上来,效果已经很可观。微调属于“锦上添花”,不是前置条件。

5.2 评估指标:不能只看mIoU

我见过很多项目只报一个“mIoU”就结束了,但在这个任务里,mIoU会掩盖很多问题。比如漏检率和误检率,它们反映的是“树有没有找到”,而IoU只反映“找到的树边界像不像”。

我额外使用四个指标:

  • 树冠计数准确率:真实标注树冠数和预测树冠数之间的误差比率,反映清点能力。
  • 召回率:正确检测到的树冠数占真实树冠数的比例,漏检越少越好。
  • 精确率:正确检测到的树冠数占所有预测树冠数的比例,误检越少越好。
  • 边界误差:用掩膜边界到真实标注边界之间的平均距离表示,通常几十厘米到几米。

在报告结果时,我习惯像下面这样做一个A/B对比表,横着能看出每阶段的作用。

方案mIoU召回率精确率计数误差边界误差
直接SAM自动掩膜0.710.620.37+28%2.3m
SAM+检测框提示0.820.810.69+11%1.1m
SAM+多相细化全流程0.890.930.91-2.6%0.4m

注意,这些数字来自某地块0.3米影像的测试集,不同数据会有浮动,但趋势是稳定的:每一相细化都在上一相基础上同时改善精度和参数稳定性。尤其是精确率,从0.37直接跳到0.91,主要靠的就是目标级重分割和多时相遇判。

5.3 一个可复现的实验记录

我挑一块约200棵树的小地块作为标准测试块,记录一下实际跑出来的数据。检测阶段用0.25置信度,候选框约240个;经过目标级SAM重分割后,得到230个掩膜;形态学精修后,掩膜数不变但mIoU提升3个百分点;多时相遇判阶段,剔除了43个非树对象,同时找回7个之前被阴影拆开的对象;最后的行距一致性检查再剔除5个,得到197个最终树冠,真实树冠数是202棵。

这5棵少数漏检,几乎全部是小树苗或重度遮阴树。这说明多相细化把大目标压得足够准了,剩下的短板已经转移到了“数据本身能不能看到”的层面,模型提升空间有限,除非换更高分辨率影像或加无人机补拍。

6. 踩坑锦囊:真实项目里最容易翻车的几个地方

6.1 漏检到底集中在哪

很多人跑完第一版就抱怨“模型漏检”,但细看漏检位置,几乎都集中在这几类:树冠被阴影一分为二的小树、位于影像边缘的残缺目标、紧挨着白房子或石头地的高反照率背景。我的做法是单独统计漏检类型,而不是笼统调阈值。如果是阴影问题,就在边界精修里增强阴影补偿;如果是边缘问题,就检查切块overlap和后处理拼接逻辑。定位问题比调参数重要得多。

6.2 切块边界处的“半棵树”问题

1024×1024切块推理时,一棵树如果正好跨在切块边界上,前一半和后一半会分别被分割成两个残缺掩膜。这可以说是遥感分割里最普遍的工程问题。

解决办法有两层。第一层,切块时overlap设到128以上,确保边界线附近的树冠在相邻两个切块里都至少有一块完整版本。第二层,在后处理合并时做“跨块仲裁”:如果两块切块输出的掩膜在重叠区域的IoU超过0.5,并且中心点距离小于一个树冠半径,就认为是同一棵树的两个结果,选择置信度高或边界更完整的那个掩膜,丢弃另一个。

不要指望模型自己“懂事”,边界拼接一定要写在后处理代码里。

6.3 显存不足与推理太慢

SAM的ViT-L和ViT-H在遥感切块上相当吃显存。如果只有一张16G显存的卡,建议直接用ViT-B,或者给切块图像做降采样。实测ViT-B在256×256输入下分割单棵树冠的速度,比ViT-H快大约4倍,而边界质量差距并没有想象中大。不要一上来就上最大模型,先验证流程,再考虑提精度。

另一个很实用的小技巧是half精度推理。SAM在half精度下输出掩膜质量几乎没有退化,显存占用却能减半。我用它把批量推理速度提升了接近一倍。

6.4 提示点落在阴影里导致掩膜残缺

给SAM传框提示时,检测框可能包含一半树冠一半阴影。SAM在框里分割时,会倾向于把阴影和树冠连成一片,或者只分割出有纹理的那一半。我在第三相边界精修里,特意加入一个“阴影方向修正”:根据影像太阳方位角估算树冠被阴影覆盖的方向,对边界凹陷做针对性补偿。这个方法看起来粗糙,但比让模型硬学阴影更可控。

6.5 别让评估结果自欺欺人

最后这个坑最隐蔽:如果你训练和测试都取自同一片果园,模型会“背”下这块地的种植模式,测试IoU非常高,但换一块地就崩。我每次做跨地块测试时,都在不同地形、不同树龄的果园上再跑一遍。如果跨地块掉点超过8个百分点,说明流程里可能出现了过拟合,优先检查特征和规则是不是太“本地化”了。多时相遇判和行距规则尤其容易过拟合到特定果园,使用时要保留可调参数。

7. 我在实验中的体会和可复用建议

做完这个项目,我最大的体会是:不要试图让一个模型一次性解决所有问题。SAM很好用,但它是个“边界生成器”,不是“目标理解器”。真正把精度从“能用”拉到“好用”的,是把它嵌进一套由粗到精的流程里,让每一阶段只专注解决一类问题。

如果只让我说一个最有用的技巧,那就是“目标级重分割”这一步——把每棵树从整体画面里抠出来单独看,很多边界问题会自然消失。第二个技巧是多时相遇判,在有条件的场景里,它的收益甚至比换个更大的模型还高。

这套流程不只适用于橄榄树,柑橘、苹果、核桃这类有明确树冠的果园种植区,都可以用同一个框架迁移,只需要更换训练样本和调整面积阈值。下一步我打算把无人机影像接进去,在更高分辨率下验证边界精度能提升到什么程度。希望这篇分享能给你一些可直接参考的思路,也欢迎你在实际复现时跟我交流踩坑情况。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进