从Segment Anything出发学习图像分割

Segment Anything模型及零样本转移实验
本文围绕Segment Anything(SA)项目展开,介绍了其任务、模型、数据引擎和数据集。SA项目建立了最大的分割数据集,模型经设计训练可零样本转移到新任务。文中还进行了零样本转移实验,涉及单点有效掩码评估、边缘检测、目标检测等任务,验证了模型在不同任务中的有效性。

最近在了解大模型,先看了一篇关于SAM大模型的应用综述,上一篇论文大概记录了一下。上篇我记到医学图像处理之后就停了,因为发现那篇虽然内容比较全,但和我相关的部分并不多,描述比较粗略,不过里面提到的参考文献还是可以看一下的。把这篇论文Segment Anything 过一遍就去看那篇里提到的医学图像分割的论文。

一 摘要

我们介绍了Segment Anything(SA)项目:一个新的任务,模型和数据集的图像分割。在数据收集循环中使用我们的高效模型,我们建立了迄今为止(到目前为止)最大的分割数据集,在1100万张许可和尊重隐私的图像上拥有超过10亿个掩模。该模型被设计和训练为提示,因此它可以将零拍摄转移到新的图像分布和任务。我们评估了它在许多任务中的能力,发现它的零射击性能令人印象深刻-通常与之前的完全监督结果相竞争甚至优于。我们在https://segment-anything.com上发布了包含1B个掩模和11M张图像的分段任意模型(SAM)和相应的数据集(SA-1B),以促进对计算机视觉基础模型的研究。

Zero-shot, One-shot和Few-shot:
ZSL就是希望我们的模型能够对其从没见过的类别进行分类,让机器具有推理能力,实现真正的智能。其中零次(Zero-shot)是指对于要分类的类别对象,一次也不学习。
这部分参考博客

二 介绍

在这项工作中,我们的目标是建立一个图像分割的基础模型。也就是说,我们寻求开发一个提示模型,并使用一个能够实现强大泛化的任务在广泛的数据集上对其进行预训练。有了这个模型,我们的目标是使用即时工程解决新数据分布上的一系列下游分割问题。
该计划的成功取决于三个组成部分**:任务、模型和数据**。为了开发它们,我们解决了以下关于图像分割的问题:

  1. 什么任务可以实现零概率泛化?

  2. 相应的模型体系结构是什么?

  3. 哪些数据可以为这项任务和模型提供支持?

这些问题纠缠在一起,需要综合解决。我们首先定义一个提示的分割任务,它足够通用,可以提供一个强大的预训练目标,并支持广泛的下游应用程序。此任务需要一个支持灵活提示的模型,并且可以在提示时实时输出分段掩码以允许交互使用。为了训练我们的模型,我们需要一个多样化的、大规模的数据源。

这段的思路值得借鉴,做科研不能照本宣科,要按照逻辑一步步解决问题

不幸的是,没有网络规模的数据来源的分割;为了解决这个问题,我们构建了一个“数据引擎”,也就是说,我们在使用我们的高效模型来协助数据收集和使用新收集的数据来改进模型之间进行迭代。接下来我们介绍每个相互关联的组件,然后是我们创建的数据集和证明我们方法有效性的实验。

三 Segment Anything 任务

我们从NLP中获得灵感,其中下一个令牌预测任务用于基础模型预训练,并通过提示工程(prompt engineering)解决各种下游任务。为了建立分割的基础模型,我们的目标是定义一个具有类似功能的任务。

prompt engineering:prompt简单的理解就是给AI模型的指令,可以是一个问题、一段文字描述,甚至可以是带有一堆参数的文字描述。prompt所提供的信息,生成对应的文本或者图片。而Prompt Engineering是一种人工智能技术,它通过设计和改进AI的prompt来提高AI的表现。Prompt Engineering的目标是创建高度有效和可控的AI系统,使其能够准确、可靠地执行特定任务。

任务。我们首先将提示的概念从NLP翻译到分割,其中提示可以是一组前景/背景点,一个粗略的框或蒙版,自由格式的文本,或者一般情况下,任何指示图像中要分割的信息。因此,提示分割任务是在给定任何提示的情况下返回一个有效的分割掩码。“有效”掩码的要求意味着,即使提示是模糊的,并且可以引用多个对象(例如,回想一下衬衫与人的例子,参见图3),输出也应该是这些对象中至少一个的合理掩码。这个需求类似于期望语言模型对不明确的提示输出一致的响应。我们之所以选择这个任务,是因为它带来了一种自然的预训练算法和一种通过提示将零射击转移到下游分割任务的通用方法。

预训练。提示分割任务提出了一种自然的预训练算法,该算法为每个训练样本模拟一系列提示(例如,点、框、掩码),并将模型的掩码预测与基本事实进行比较。我们从交互式分割中采用了这种方法[109,70],尽管与交互式分割不同,交互式分割的目的是在足够的用户输入后最终预测一个有效的掩码,但我们的目标是始终预测任何提示的有效掩码,即使提示是模糊的。这确保了预训练模型在涉及歧义的用例中是有效的,包括我们四 数据引擎所要求的自动注释。我们注意到,在这个任务中表现良好是具有挑战性的,需要专门的建模和训练损失选择,我们在三中讨论过。

Zero-shot转移。直观地说,我们的预训练任务赋予了模型在推理时对任何提示作出适当响应的能力,因此下游任务可以通过设计适当的提示来解决。例如,如果有一个猫的边界框检测器,猫实例分割可以通过提供检测器的框输出作为提示给我们的模型来解决。一般来说,许多实际的分割任务都可以作为提示。除了自动数据集标记,我们在七 实验部分中探索了五个不同的示例任务

相关的任务。分割是一个广泛的领域:有交互式分割,边缘检测,超像素化,目标建议生成,前景分割,语义分割,实例分割,全景分割等。我们的提示分割任务的目标是产生一个广泛的功能模型,可以适应许多(尽管不是全部)现有的和新的分割任务。这种能力是任务泛化的一种形式[26]。请注意,这与之前在多任务分割系统上的工作不同。在多任务系统中,单个模型执行一组固定的任务,例如联合语义分割、实例分割和全视分割,但训练和测试任务是相同的。我们工作中的一个重要区别是,训练用于提示分割的模型可以作为更大系统中的组件在推理时间执行新的不同任务,例如,执行实例分割,提示分割模型与现有的对象检测器相结合。

语义分割、实例分割、全景分割:
语义分割是对图像中的每个像素打上类别的标签;
实例分割是目标检测和语义分割地结合,在图像中将目标检测出来(目标检测),然后对每个像素打上标签(语义分割)。实力分割会分割同类的不同实例;
全景分割是语义分割和实力分割地结合,既要将所有目标都检测出来,又要区分出同个类别中的不同实例。
参考这里

讨论。提示和组合是功能强大的工具,可以以可扩展的方式使用单个模型,从而潜在地完成模型设计时未知的任务。这种方法类似于其他基础模型的使用方式,例如CLIP[82]是DALL·E[83]图像生成系统的文本-图像对齐组件。我们预计,可组合的系统设计,由提示工程等技术提供动力,将比专门为固定任务集训练

一、基本概念 1. 什么是目标检测 目标检测(Object Detection)的任务是找出图像中所有感兴趣的目标(物体),确定它们的类别和位置,是计算机视觉领域的核心问题之一。由于各类物体有不同的外观、形状和姿态,加上成像时光照、遮挡等因素的干扰,目标检测一直是计算机视觉领域最具有挑战性的问题。 计算机视觉中关于图像识别有四大类任务: (1)分类-Classification:解决“是什么?”的问题,即给定一张图片或一段视频判断里面包含什么类别的目标。 (2)定位-Location:解决“在哪里?”的问题,即定位出这个目标的的位置。 (3)检测-Detection:解决“在哪里?是什么?”的问题,即定位出这个目标的位置并且知道目标物是什么。 (4)分割-Segmentation:分为实例的分割(Instance-level)和场景分割(Scene-level),解决“每一个像素属于哪个目标物或场景”的问题。 所以,目标检测是一个分类、回归问题的叠加。 2. 目标检测的核心问题 (1)分类问题:即图片(或某个区域)中的图像属于哪个类别。 (2)定位问题:目标可能出现在图像的任何位置。 (3)大小问题:目标有各种不同的大小。 (4)形状问题:目标可能有各种不同的形状。 3. 目标检测算法分类 基于深度学习的目标检测算法主要分为两类:Two stage和One stage。 1)Tow Stage 先进行区域生成,该区域称之为region proposal(简称RP,一个有可能包含待检物体的预选框),再通过卷积神经网络进行样本分类。 任务流程:特征提取 --> 生成RP --> 分类/定位回归。 常见tow stage目标检测算法有:R-CNN、SPP-Net、Fast R-CNN、Faster R-CNN和R-FCN等。 2)One Stage 不用RP,直接在网络中提取特征来预测物体分类和位置。 任务流程:特征提取–> 分类/定位回归。 常见的one stage目标检测算法有:OverFeat、YOLOv1、YOLOv2、YOLOv3、SSD和RetinaNet等。 4. 目标检测应用 1)人脸检测 智能门控 员工考勤签到 智慧超市 人脸支付 车站、机场实名认证 公共安全:逃犯抓捕、走失人员检测 2)行人检测 智能辅助驾驶 智能监控 暴恐检测(根据面相识别暴恐倾向) 移动侦测、区域入侵检测、安全帽/安全带检测 3)车辆检测 自动驾驶 违章查询、关键通道检测 广告检测(检测广告中的车辆类型,弹出链接) 4)遥感检测 大地遥感,如土地使用、公路、水渠、河流监控 农作物监控 军事检测 二、目标检测原理 目标检测分为两大系列——RCNN系列和YOLO系列,RCNN系列是基于区域检测的代表性算法,YOLO是基于区域提取的代表性算法,另外还有著名的SSD是基于前两个系列的改进。 1. 候选区域产生 很多目标检测技术都会涉及候选框(bounding boxes)的生成,物体候选框获取当前主要使用图像分割与区域生长技术。区域生长(合并)主要由于检测图像中存在的物体具有局部区域相似性(颜色、纹理等)。目标识别与图像分割技术的发展进一步推动有效提取图像中信息。 1)滑动窗口 通过滑窗法流程图可以很清晰理解其主要思路:首先对输入图像进行不同窗口大小的滑窗进行从左往右、从上到下的滑动。每次滑动时候对当前窗口执行分类器(分类器是事先训练好的)。如果当前窗口得到较高的分类概率,则认为检测到了物体。对每个不同窗口大小的滑窗都进行检测后,会得到不同窗口检测到的物体标记,这些窗口大小会存在重复较高的部分,最后采用非极大值抑制(Non-Maximum Suppression, NMS)的方法进行筛选。最终,经过NMS筛选后获得检测到的物体。 滑窗法简单易于理解,但是不同窗口大小进行图像全局搜索导致效率低下,而且设计窗口大小时候还需要考虑物体的长宽比。所以,对于实时性要求
### 使用 Segment Anything 模型进行遥感图像分割 #### 准备工作 为了使用 Segment Anything Model (SAM) 进行遥感图像的分割,需先安装必要的库并加载预训练模型。这通常涉及配置环境变量和导入所需的Python包。 ```python import torch from segment_anything import sam_model_registry, SamPredictor import cv2 import numpy as np ``` #### 加载模型与初始化预测器 指定 `image_path` 和 `sam_checkpoint` 参数来指明输入图片的位置以及之前下载好的 SAM 权重文件位置;同时定义使用的设备(CPU 或 GPU)及所选模型版本[^2]。 ```python def load_sam(model_type="vit_b", device='cuda'): checkpoint_url = "path/to/sam_vit_b_01ec64.pth" model = sam_model_registry[model_type](checkpoint=checkpoint_url).to(device=device) predictor = SamPredictor(model) return predictor ``` #### 图像读取与处理 针对特定的应用场景——即地理遥感中的卫星影像,需要确保能够正确解析多光谱或高分辨率的数据集格式,比如GeoTIFF文件。这里假设已经有一个合适的函数可以从给定路径中读入此类图像,并将其转换成适合喂给神经网络的形式。 ```python def read_image(image_path): img = cv2.imread(image_path) img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) return img_rgb ``` #### 执行分割操作 利用上述准备好的工具链,在实际执行阶段只需调用简单的API接口即可完成目标区域的选择与掩码生成过程。对于遥感领域而言,这意味着可以根据兴趣点自动勾勒出边界轮廓,从而辅助后续的空间分析任务[^1]。 ```python predictor = load_sam() img = read_image('sentinel2.tif') predictor.set_image(img) input_point = np.array([[500, 375]]) # 用户交互式点击得到的兴趣点坐标 input_label = np.array([1]) # 对应标签(前景/背景),此处设为前景 masks, scores, logits = predictor.predict( point_coords=input_point, point_labels=input_label, multimask_output=True, ) ``` #### 输出结果保存 最后一步是将获得的结果导出至外部存储介质以便进一步查看或与其他GIS软件集成。此部分涉及到创建Shapefile或其他矢量图形文件的操作。 ```python import shapely.geometry import geopandas as gpd mask = masks[np.argmax(scores)] # 获取最佳匹配度下的二值化蒙版图层 polygons = [] for i in range(mask.shape[-1]): contours, _ = cv2.findContours((mask[:, :, i]*255).astype(np.uint8), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) polygon = [shapely.geometry.Polygon(contour.reshape(-1, 2)) for contour in contours if len(contour)>2] polygons.extend(polygon) gdf = gpd.GeoDataFrame({'geometry': polygons}) gdf.to_file(filename='output.shp', driver='ESRI Shapefile') ```
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值