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

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 modelvit_b366M

下载后重命名为

sam_vit_b.pth

ViT-L SAM modelvit_l1220M

下载后重命名为

sam_vit_l.pth

ViT-H SAM modelvit_h2504M

下载后重命名为

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

 分割结果如下:

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/34307.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

面对“神奇的甲方”:如何应对匪夷所思的需求

在工作中,我们常常会遇到一些“神奇的甲方”,他们总是能给我们带来匪夷所思甚至无厘头的需求。本文将分享作者的经历,并提供一些建议,帮助读者应对这些“无理的需求”。 文章目录 方向一:分享那些你遇到的无理需求方向…

简单的手机记事本怎么把内容标记为完成状态?

很多人平时会在手机记事本上记录一些自己身边需要记住的事情,有的事情做完之后不想删除,又想要和未完成的内容区分开,那么这种情况下可以将它标记为已完成状态。简单的手机记事本怎么把内容标记为完成状态呢?以iPhone手机端敬业签…

【应用笔记】CW32 电容式触摸按键设计指南

前言 CW32 电容式触摸按键设计指南向客户提供一种利用 CW32 内部资源结合软件编程实现电容式触摸按键有效 触摸检测的方法。本指南的内容重点在于工作原理、软件检测过程以及调试指引。 利用芯源半导体的 CW32 系列小规模 MCU 的 IO、比较器、定时器、高速高精度内置 RC 时钟…

技术分享| 融合通讯的架构介绍

在融合通讯中,我们经常听到如下一些术语:MCU服务,SFU架构,MESH架构,星形网络等等。很多客户听到这些数据都是一脸雾水,经常说我们就是要一个可以把多种设备拉到同一个会议中,怎么搞这么复杂。今…

Web安全-Godzilla(哥斯拉)Webshell管理工具使用

为方便您的阅读,可点击下方蓝色字体,进行跳转↓↓↓ 01 工具下载地址02 运行环境03 工具介绍04 使用案例 01 工具下载地址 https://github.com/BeichenDream/Godzilla点击页面右侧"releases",进入工具的版本下载页面。 在个人终端…

[Qt 教程之Widgets模块] —— QFontComboBox 字体选择器

Qt系列教程总目录 文章目录 3.2.1 创建 QFontComboBox3.2.2 成员函数1. 书写系统2. 字体过滤器3. 当前字体4. 信号 该控件用于选择字体,在一些软件中经常有类似控件,如下: Microsoft Office: Photoshop: QFontComboB…

QT调用glog日志流程

glog日志库是Google开源的轻量级的日志库,平时在开发过程中经常要使用到日志,本篇记录Qt项目使用glog日志库的记录。 1.首先下载cmake,Download | CMake 安装设置环境变量,检查安装情况 2.下载glog源码 git clone https://git…

JMeter录制HTTPS脚本解决办法

目录 前言: 背景 解决方法 前言: 在使用JMeter录制HTTPS脚本时,可能会遇到一些问题,例如SSL证书错误或请求失败等。解决这些问题的一种常见的方法是通过安装并信任服务器的SSL证书来解决。 背景 在对某项目进行脚本录制的时…

Django框架-5

路由系统 通过URL(Uniform Resource Locator,统一资源定位符)可以访问互联网上的资源——用户通过 浏览器向指定URL发起请求,Web服务器接收请求并返回用户请求的资源,因此可以将URL视为用户与服务器之间交互的桥梁。 …

Scrapy框架之MongoDB通过配置文件管理参数--Linux安装MongoDB--图形管理工具

目录 MongoDB通过配置文件 问题 解决方案 步骤 提示 Linux安装MongoDB 环境 下载依赖与安装包 解压安装 MongoDB GUI管理工具 独立软件GUI软件 Robo 3T使用 VSCode集成GUI插件 MongoDB通过配置文件 问题 启动MongoDB时,编写参数太麻烦 解决方案 通过配…

MATLAB App Designer基础教程 Matlab GUI入门(四)

坐标轴控件 axis 函数绘图方法技巧 作用: 绘制函数图像显示图像(jpg png tiff) 学习内容 App designer中 plot 和命令行中的 plot函数的不同;如何在坐标轴空间中显示两个函数图像;智能缩进 (Ctrl I&am…

Linux——进程通信之共享内存

目录 一. 回顾上文 二.共享内存 1.定义 2.特点: 3.实现步骤: 如下为成功链接共享内存使用权的完整步骤: 4.函数介绍 4.1shmget函数 4.1.2参数介绍 4.2ftok函数: 4.2.1参数介绍 关于ftok(); shmget();函数的代码实验…

学习Kotlin~类

类 类的field 类定义的每一个属性,kotlin都会产生一个filed,一个setter(),一个getter()field用来存储属性数据,不能直接定义,kotlin会封装,保护它里面数据,只暴露给getter和setter使用只有可变属性才有setter方法需要…

探索 Jetson Nano 为 myCobot 280 机械臂提供的强大功能

探索 Jetson Nano 为 myCobot 280 提供的强大功能,机器人技术的一个有前途的组合 介绍 近年来,科学技术的发展给我们的生活带来了许多新的产品和服务,包括机器人在各个领域的集成。机器人已经成为我们生活中必不可少的一部分,从…

Vim 自定义配色

本文首发于我的个人博客,欢迎点击访问,无广告节面简洁! 最近重新开始学习Vim装上了WSL2,但发现Windows Terminal和vim的组合还是有很多问题需要解决的,由其默认的配色在某些状态下根本看不清字体,所以折腾…

Nginx | 苹果电脑Mac安装和验证Nginx服务过程记录

common wx:CodingTechWork,一起学习进步。 引言 本文主要总结如何在Mac电脑上进行Nginx服务的安装,重点讲解使用brew命令进行安装和验证的过程及问题记录。 安装步骤 安装过程记录 查看nginx信息 首先使用命令brew info nginx进行本机ng…

《Pytorch深度学习和图神经网络(卷 1)》学习笔记——第七章

这一章内容有点丰富,多用了一些时间,实例就有四五个。 这章内容是真多啊!(学完之后又回到开头感叹) 大脑分级处理机制: 将图像从基础像素到局部信息再到整体信息 即将图片由低级特征到高级特征进行逐级计…

基于群组实现从 Azure AD 到极狐GitLab 的单点登录

目录 配置单点登录 在 Azure AD 中创建企业应用 SAML 基础配置 配置 Azure “Attributes & Claims” 配置用户同步 在极狐GitLab 创建 SCIM Token 配置 Azure Provisioning Azure 手动用户预配 测试单点登录 Azure 自动用户同步 配置群组同步 配置 SAML 群组链…

打jar包

pom文件指定打包的类型是jar&#xff0c;并指定启动主类 <packaging>jar</packaging><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-jar-plugin</artifactId><version>…

什么条件下会出现死锁,如何避免?

文章目录 一、什么是死锁二、产生死锁的原因&#xff1a;三、如何避免死锁&#xff1a; 一、什么是死锁 死锁&#xff0c;简单来说就是两个或者两个以上的线程在执行过程中&#xff0c;去争夺同一个共享资源导致相互等待的现象。如果没有外部干预&#xff0c;线程会一直处于阻塞…