计算机视觉:分割一切AI大模型segment-anything

2023-11-08

1 segment-anything介绍

Segment Anything Model (SAM)来源于Facebook公司Meta AI实验室。据Mata实验室介绍,SAM 已经学会了关于物体的一般概念,并且它可以为任何图像或视频中的任何物体生成 mask,甚至包括在训练过程中没有遇到过的物体和图像类型。SAM 足够通用,可以涵盖广泛的用例,并且可以在新的图像领域上即开即用,无需额外的训练。在深度学习领域,这种能力通常被称为零样本迁移(这种能力正是GPT4 震惊世界的一大原因).

图像分割师计算机视觉中的一项关键任务,SAM是第一个致力于图像分割的基础模型。在此之前,分割作为计算机视觉的核心任务,已经得到广泛应用。但是,为特定任务创建准确的分割模型通常需要技术专家进行高度专业化的工作,此外,该项任务还需要大量的领域标注数据,种种因素限制了图像分割的进一步发展。

SAM具有极强的泛化能力,能够泛化到新任务和新领域。这种灵活性在图像分割领域尚属首创。最强大的是,Meta实现了一个完全不同的CV范式,你可以在一个统一框架prompt encoder内,指定一个点、一个边界框、一句话,直接一键分割出物体。

论文地址:segment-anything

1.1 SAM数据集

SA-1B是迄今为止世界上最大的分割数据集。包括来自11M许可和隐私保护图像的超过1B个掩码。SA-1B,使用我们的数据引擎的最后阶段完全自动收集,mask是高质量和多样性的。Meta AI与摄影师合作的供应商那里授权了一组1100万张新图片。这些图像是高分辨率的(平均3300×4950像素),Meta AI将发布其最短边设置为1500像素的降采样图像。明显高于许多现有的视觉数据集(COCO 的480×640像素)

SA-1B 的图像来自多个国家/地区的照片提供商,SA-1B比第二大的Open Images数据集有11倍多的图像和400倍多的掩码,并且经人工评估研究证实,这些掩码具有高质量和多样性,在某些情况下甚至在质量上可与之前更小、完全手动注释的数据集的掩码相媲美。

1.2 SAM模型

网络总共有三个部分:image_encoder、prompt_encoder和mask_decoder。

  •  Image encoder:SAM中的图像编码器采用标准的vit作为图像编码器,原始图像被等比和padding的缩放到1024大小,然后采用kernel size 为16,stride为16的卷积将图像离散化为64x64X768(W,H,C)的向量,向量在W和C上背顺序展平后再进入多层的transformer encoder,vit输出的向量再通过两层的卷积(kernel分别为1和3,每层输出接入layer norm2d)压缩到特征维度为256,具体的图像编码器支持vit-h,vit-l,vit-b,vit经过了MAE方式的预训练,MAE属于图像中自监督学习的一种,在MAE中原始图像如vit切割成不重叠的patch,保留部分patch进入vit架构的encoder进行学习patch的表示,学习到的patch表示和mask(灰色)的表示按照原始的patch顺序输入到vit架构的decoder,得到复原图像。loss为mask部分复原前后的l2 loss。训练完成后我们只使用encoder来提取图像特征
  •  Prompt encoder:基于分割的任务需求,SAM 支持的prompt包含 point,bbox,free text。在编码方式上,点、bbox(左上点,右下点)采用sincos的位置编码embedding+学习的类别的embedding(一共5种类别,前景和后景的点类别,非点类别、bbox的左上类别、右下类别)
  • mask decoder:分别采用clip(ViT-L/14@336px) 预训练好的text encoder 作为文本编码器,image encoder 作为图像编码器取代SAM的图像编码器(ViT-L/14@336px 输出的特征维度为768,而point和bbox的特征维度为256,所以还存在全连接进行特征维度对齐),将文本特征向量和图像特征向量进行l2 norm作为下一步使用。

1.3 数据引擎data engine

为了实现对新数据分布的强泛化,需要在大量和不同的掩码集上训练SAM。在线获取数据缺少mask标注。SAM的方案是构建一个“数据引擎”,SAM与model in the loop的数据集注释共同开发的SAM模型。分三个阶段:辅助手动、半自动和全自动。在第一阶段,SAM协助注释器对掩码进行注释,类似于经典的交互式分割设置。在第二阶段,SAM可以通过提示可能的对象位置来为对象子集自动生成掩码,注释器专注于对其余对象的注释,帮助增加掩码的多样性。在最后一个阶段,我们用一个规则的前景点网格提示SAM,平均每张图像产生100个高质量的掩模。
 

1.4 SAM模型的优势和不同?

与传统图像分割方法相比,Segment Anything模型的优势和不同之处主要有以下几点:

  • 不需要大量标注数据:传统的图像分割方法需要大量标注数据才能训练模型,而Segment Anything模型可以在不需要大量标注数据的情况下训练模型。
  • 可以对任何物体进行分割:传统的图像分割方法通常只能对特定类型的物体进行分割,而Segment Anything模型可以对图像中的任何物体进行分割。
  • 更准确:与传统的图像分割方法相比,Segment Anything模型可以更准确地对图像中的物体进行分割。
  • 更快速:由于Segment Anything模型不需要大量标注数据,因此可以更快地训练模型。

通过使用Segment Anything模型,计算机视觉领域的研究人员和开发人员可以更轻松地训练模型,并提高计算机视觉应用程序的性能。

1.5 SAM模型未来发展方向

Segment Anything模型的未来发展方向和应用场景是非常广泛的。该模型可以用于许多计算机视觉应用程序,例如自动驾驶汽车、智能家居、安全监控、医疗图像分析等。此外,该模型还可以用于图像编辑和视频编辑,例如删除不需要的对象、更改背景等。这些应用程序将使我们的生活更加便利和安全。

Segment Anything模型的发布也可能会对计算机视觉行业产生重大影响。它可以帮助研究人员更好地理解图像分割问题,并提供一种新的方法来解决这个问题。此外,它还可以促进计算机视觉领域的进一步研究和发展

2 SAM运行环境构建

2.1 conda环境准备

        conda环境准备详见:annoconda

2.2 运行环境安装

conda create -n sam python=3.9
activate sam


pip install torch==1.9.0
pip install torchaudio==0.9.0
pip install torchvision==0.10.0

pip install opencv-python==4.7.0.72
 
pip install pycocotools==2.0.6
pip install matplotlib==3.7.1
pip install onnxruntime==1.15.1
pip install onnx==1.14.0


git clone https://github.com/facebookresearch/segment-anything
cd segment-anything
pip install -e .

2.3 模型下载

SAM提供了三种型号的预训练模型,分别如下:

模型 类型 大小 描述
ViT-B SAM model vit_b 366M

下载后重命名为

sam_vit_b.pth

ViT-L SAM model vit_l 1220M

下载后重命名为

sam_vit_l.pth

ViT-H SAM model vit_h 2504M

下载后重命名为

sam_vit_h.pth

模型下载后,存储到根目录的checkpoint文件夹下,存储完成后显示如下:

ll checkpoint/
总用量 4090944
-rw-r--r-- 1 root root  375042383 6月  26 19:57 sam_vit_b.pth
-rw-r--r-- 1 root root 2564550879 6月  26 20:01 sam_vit_h.pth
-rw-r--r-- 1 root root 1249524607 6月  26 20:02 sam_vit_l.pth

3 SAM图片分割

原始图片存储在根目录的data文件夹下,./data/cat-dog.jpg,图片内容如下:

3.1 对指定位置进行分割

使用vit_b模型对图片进行指定位置分割,分割代码如下:

from segment_anything import SamPredictor, sam_model_registry
import numpy as np
import matplotlib.pyplot as plt
import cv2
import torch


def show_mask(mask, ax, random_color=False):
    if random_color:
        color = np.concatenate([np.random.random(3), np.array([0.6])], axis=0)
    else:
        color = np.array([30 / 255, 144 / 255, 255 / 255, 0.6])
    h, w = mask.shape[-2:]
    mask_image = mask.reshape(h, w, 1) * color.reshape(1, 1, -1)
    ax.imshow(mask_image)


def show_points(coords, labels, ax, marker_size=375):
    pos_points = coords[labels == 1]
    neg_points = coords[labels == 0]
    ax.scatter(pos_points[:, 0], pos_points[:, 1], color='green', marker='*', s=marker_size, edgecolor='white',
               linewidth=1.25)
    ax.scatter(neg_points[:, 0], neg_points[:, 1], color='red', marker='*', s=marker_size, edgecolor='white',
               linewidth=1.25)

def show_box(box, ax):
    x0, y0 = box[0], box[1]
    w, h = box[2] - box[0], box[3] - box[1]
    ax.add_patch(plt.Rectangle((x0, y0), w, h, edgecolor='green', facecolor=(0, 0, 0, 0), lw=2))


image = cv2.imread('./data/cat-dog.jpg')
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
plt.figure(figsize=(10, 10))
plt.imshow(image)
plt.axis('on')
plt.show()

sam_checkpoint = "./checkpoint/sam_vit_b.pth"
model_type = "vit_b"
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

sam = sam_model_registry[model_type](checkpoint=sam_checkpoint)
sam.to(device=device)

predictor = SamPredictor(sam)

input_point = np.array([[500, 375]])
input_label = np.array([1])

plt.figure(figsize=(10, 10))
plt.imshow(image)
show_points(input_point, input_label, plt.gca())
plt.axis('on')
plt.show()

predictor.set_image(image)  # 设置要分割的图像

masks, scores, logits = predictor.predict(
    point_coords=input_point,
    point_labels=input_label,
    multimask_output=True,
)

for i, (mask, score) in enumerate(zip(masks, scores)):
    plt.figure(figsize=(10, 10))
    plt.imshow(image)
    show_mask(mask, plt.gca())
    show_points(input_point, input_label, plt.gca())
    plt.title(f"Mask {i + 1}, Score: {score:.3f}", fontsize=18)
    plt.axis('off')
    plt.show()

运行代码后,得到的分割效果如下:

 3.2 对整个图片进行分割

使用vit_b模型对整个图片进行分割,分割代码如下:

from segment_anything import SamAutomaticMaskGenerator, sam_model_registry
import numpy as np
import matplotlib.pyplot as plt
import cv2
import torch


def show_mask(mask, ax, random_color=False):
    if random_color:
        color = np.concatenate([np.random.random(3), np.array([0.6])], axis=0)
    else:
        color = np.array([30 / 255, 144 / 255, 255 / 255, 0.6])
    h, w = mask.shape[-2:]
    mask_image = mask.reshape(h, w, 1) * color.reshape(1, 1, -1)
    ax.imshow(mask_image)


def show_points(coords, labels, ax, marker_size=375):
    pos_points = coords[labels == 1]
    neg_points = coords[labels == 0]
    ax.scatter(pos_points[:, 0], pos_points[:, 1], color='green', marker='*', s=marker_size, edgecolor='white',
               linewidth=1.25)
    ax.scatter(neg_points[:, 0], neg_points[:, 1], color='red', marker='*', s=marker_size, edgecolor='white',
               linewidth=1.25)


def show_box(box, ax):
    x0, y0 = box[0], box[1]
    w, h = box[2] - box[0], box[3] - box[1]
    ax.add_patch(plt.Rectangle((x0, y0), w, h, edgecolor='green', facecolor=(0, 0, 0, 0), lw=2))


image = cv2.imread('./data/cat-dog.jpg')
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
plt.figure(figsize=(10, 10))
plt.imshow(image)
plt.axis('on')
plt.show()

sam_checkpoint = "./checkpoint/sam_vit_b.pth"
model_type = "vit_b"
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

sam = sam_model_registry[model_type](checkpoint=sam_checkpoint)
sam.to(device=device)

mask_generator = SamAutomaticMaskGenerator(sam)
masks = mask_generator.generate(image)

plt.figure(figsize=(10, 10))
plt.imshow(image)
plt.axis('on')
plt.show()

plt.figure(figsize=(10, 10))
plt.imshow(image)
for i, mask in enumerate(masks):
    show_mask(mask['segmentation'], plt.gca(), True)
    # plt.title(f"Mask {i + 1}, Score: {mask['stability_score']:.3f}", fontsize=18)
plt.axis('off')
plt.show()

经过一段时间运行,分割效果如下:

 3.3 通过命令行进行分割

通过命令行,使用vit_b的模型对图片进行分割,分割后的结果存储在根目录的output文件夹下:

python scripts/amg.py --checkpoint ./checkpoint/sam_vit_b.pth --model-type vit_b --input ./data/cat-dog.jpg --output ./output

 分割结果如下:

有任何问题欢迎随时交流,如果您觉得有帮助,欢迎点赞、关注、收藏

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

计算机视觉:分割一切AI大模型segment-anything 的相关文章

随机推荐

  • 用虚拟机安装linux程序

    其实这是一个很简单的工作 大牛不要嘲笑 这里只是写一个简单的流程 首先 是使用的软件 虚拟机程序Oracle VM VirtualBox http www oracle com technetwork server storage virt
  • IP地址的分类及子网掩码的计算

    目录 一 什么是IP地址 IP地址的作用及其种类 二 分类的IP地址 三 无分类编址 四 网络号 主机号和子网掩码的计算 一 1 IP地址 整个互联网中 分配给每一个主机在全世界范围内唯一的32位二进制码 2 IP地址的表示方法 为了可读性
  • Mybatis-Plus的详细使用

    一 MyBatisPlus概述 需要的基础 MyBatis Spring SpringMVC学完 为什么要学习呢 它可以节省我们大量的工作时间 所有的JDBC都可以自动化完成 JPA tk mapper MyBatisPlus 简介 是什么
  • 线上流量特训营:暴力引流10W+中小卖家流量破局技巧等

    新标题 突破流量瓶颈 线上流量特训营助力中小卖家引爆10W 流量的破局技巧 文章 引言 100字 线上流量特训营是一项旨在帮助中小卖家突破流量瓶颈的破局技巧 通过学习特训营提供的精选流量引爆策略 中小卖家可以迅速吸引超过10W的流量 实现业
  • L1-5 试试手气 (15 分)

    我们知道一个骰子有 6 个面 分别刻了 1 到 6 个点 下面给你 6 个骰子的初始状态 即它们朝上一面的点数 让你一把抓起摇出另一套结果 假设你摇骰子的手段特别精妙 每次摇出的结果都满足以下两个条件 1 每个骰子摇出的点数都跟它之前任何一
  • FWT 详解 知识点

    前言 扯淡 可以跳过 其实去年清华集训之后就想写这篇文章了 但是写了一会发现有点说不明白话 于是受限于语文水平一直没有写 前几天给人当面讲了一遍 感觉大概可以BB明白些了 picks的博客里就写着fwt怎么做 然而他并没有写为什么这样是对的
  • 【微服务架构】面向故障设计微服务架构

    微服务架构可以通过定义明确的服务边界隔离故障 但就像在每个分布式系统中一样 网络 硬件或应用程序级别问题的可能性更高 由于服务依赖关系 任何组件都可能对其消费者暂时不可用 为了最大限度地减少部分中断的影响 我们需要构建可以优雅地响应某些类型
  • 爬取上交所和深交所的年报问询函到Excel

    注意事项 需要安装一些包 如pdfminer pdfminer3k pdfplumber等 pdfminer不能解析上交所问询函 使用解析功能更为强大的pdfplumber可以解析 但是内容上可能会出现个别字重复的现象 pdfminer3k
  • 区间预测

    区间预测 MATLAB实现基于QRCNN BiGRU Multihead Attention多头注意力卷积双向门控循环单元多变量时间序列区间预测 目录 区间预测 MATLAB实现基于QRCNN BiGRU Multihead Attenti
  • Spring Boot 学习笔记整理

    spring boot 笔记 1 配置文件 1 application properties 2 application yml 作用 修改spring boot的默认设置 YAML 比XML和JSON更适合做配置文件 以数据为中心 2 Y
  • 解决鼠标右键没有文本

    解决鼠标右键没有文本文档 打开注册表 win r 输入 regedit 2 找到 txt 将默认值改为 txtfile 查看shellNew项是否存在 不存在新建 存在则改变 这个字符串值为空 F5刷新一下 或者
  • OLE接口详解

    所有 OLE Api 和接口的目的 本页 摘要 详细信息 常规 初始化和内存管理 远程处理 自定义服务 服务注册 DLL 服务器管理 杂项 COM 函数 命名 名字对象 结构化的存储 永久对象 每个事件的通知 统一数据传输 可查看对象 标准
  • HarmonyOS 自定义页面请求与前端页面调试

    一 自定义页面请求响应 Web 组件支持在应用拦截到页面请求后自定义响应请求能力 开发者通过onInterceptRequest 接口来实现自定义资源请求响应 自定义请求能力可以用于开发者自定义 Web 页面响应 自定义文件资源响应等场景
  • 每日一题:走路

    走路 题目 Daimayuan Online Judge f i j 表示第i步能否走到第j阶 include
  • uniapp打包微信小程序主包过大问题

    问题 在用uniapp打包微信小程序时提示文件超过了2M不让上传 主包中的vendor js太大1 7M有的甚至更大 解决 在HbuildX中运行时勾选上运行压缩 在微信开发者工具中上传时勾选上上传压缩 在manifest json中检查分
  • C语言 .c文件 到 .exe文件过程

    预处理 预处理相当于根据预处理命令组装成新的 C 程序 不过常以 i 为扩展名 编 译 将得到的 i 文件翻译成汇编代码 s 文件 汇 编 将汇编文件翻译成机器指令 并打包成可重定位目标程序的 o 文件 该文件是二进制文件 字节编码是机器指
  • OculusRiftS与Unity.UI的交互(1)-总览

    使用OculusIntegration包 VRTK还没有测试过 OculusIntegration提供的场景 包含了 键盘交互 VR摄像机 画布 凝视位置 光标 等节点 总览 这是默认的OVR UI场景的节点设置 之后 根据自身场景的需要
  • ARouter解析五:IoC与依赖注入

    终于来到了ARouter解析的第五篇了 前面陆陆续续分享了四篇ARouter框架的使用和源码内容 ARouter解析一 基本使用及页面注册源码解析ARouter解析二 页面跳转源码分析ARouter解析三 URL跳转本地页面源码分析ARou
  • 计算几何02_三次样条曲线

    一 样条 样条 Spline 函数是由舍恩伯格于1946年提出的 样条是富有弹性的细木条或有机玻璃条 它的作用相当于 万能 曲线板 早期船舶 汽车 飞机放样时用铅压铁压住样条 使其通过一系列型值点 调整压铁达到设计要求后绘制其曲线 称为样条
  • 计算机视觉:分割一切AI大模型segment-anything

    1 segment anything介绍 Segment Anything Model SAM 来源于Facebook公司Meta AI实验室 据Mata实验室介绍 SAM 已经学会了关于物体的一般概念 并且它可以为任何图像或视频中的任何物