背景

其实已经做过一次了,但上次做得实在是太简易,于是重新制定技术路线做了个新的。

分析

上回说到基于CNN的分割,因为必须要扩大特征值感受野,所以分割出来的mask跟闹着玩的一样,极其不精细。于是选择了CNN目标检测,把目标的图像抠出来(减少背景噪声),再Sobel检测边缘。挺草率的不是吗?

换一个角度分析,既然深度学习分割得到的mask不够精细,那么去优化这个mask就好了嘛。分两步走,第一步是优化深度学习分割本身,第二个是优化已生成的mask顶点。

方案

1.优化深度学习分割本身:CNN要扩大特征值感受野才能分类,那么我换没有感受野概念的transformer是不是就能够精细一些了呢?尝试了一下SAM2,的确如此,但是我不是要分割一切,所以我要给SAM2提供prompt点(总不能指望我为了这么点小活儿直接训练大模型去吧)。
于是我就直接抄起了YOLOv8-seg,先分割一个目标,不精细没关系,我只要在这个不精细的mask里选择一些点作为prompt投喂给SAM2就好了。至于在mask里合理选择点的方法嘛,显而易见,几何中心肯定是没问题的,我能保证这类目标的几何中心一定在多边形内部。但是光有几何中心还是少了点,就自动标注的经验来看,需要多提供一些点才能够比较准地分割。
进一步地,这类目标可以大体视为是矩形的,因位姿的不同,可能出现h>w的情况(正视),也可能出现h<w的情况(侧视)。正视时,prompt基本上可以在矩形内远离左上和右上的部分随便选。侧视时,尽可能在几何中心所在行的下部选,因为上部存在很多镂空。依据这个策略,进行“科学的”五点采样(好吧并不科学,但是采样起码在mask内)。就这样提供了prompt。
然后得知SAM2提供3个输出,经过对比,当输出2置信度很高(大于0.9)时,输出2的效果一定是最好的。如果输出2的置信度没有达到0.9,即使它的置信度是最高的,它的效果也没有输出1和输出3中置信度更高的那个结果好。然后依据这个策略又进行了一波三个结果的筛选。当然调整的时候有的结果是多输出合并的,这些都是实验结果,经验只和具体目标类型相关,就不说了。
接下来又发现了,即使是SAM2,分割大目标的时候还是不太行,它会把大目标的各部分组成拆成小目标。于是又进行了多尺度分割。说起来很简单,通过padding和裁剪,生成了大中小三个尺度的图像,然后分别进行分割。分割结果映射回原来的尺度上。三个尺度共9个结果还是依据上边的方法进行结果筛选。

2.已经有了比较精细的分割结果了,接下来就是进一步去优化mask。这个说来也很简单:

计算梯度图
while 顶点数量 < 某个值 {
    for 三个相邻顶点 in 所有顶点 {
        在梯度图中,以中间顶点为起点,沿法向搜索局部梯度最大值
        更新中间顶点坐标至局部梯度最大点
    }
    在每两个顶点中间内插一个顶点
}

结果

精细得不像是计算机搞出来的

如果觉得我的文章对你有用,请随意赞赏