# Segment Anything

## 模型介绍

SAM是23年4月发布的先进图像分割模型。SAM分为图像编码器和快速提示编码器/掩码解码器，可以重用相同的image embedding图像嵌入（并摊销其成本）与不同的提示。给定image embedding图像嵌入，提示编码器和掩码解码器可以在web浏览器中预测掩码。为了使SAM实现模糊感知，设计它来预测单个提示的多个掩码，从而使SAM能够自然地处理模糊性。通过SAM模型，创建了一个包含1B个掩模和11M张图像的分段任意模型(SAM)和相应的数据集(SA-1B)，以促进对计算机视觉基础模型的研究。

数据集标注问题，分为3个阶段。
1.SAM辅助人工标注

最开始的SAM使用coco数据集训练，当有了一定的标注数据集之后，会用新的标注数据重新训练，数据集多起来以后，会增加模型的复杂程度，比如把ViT-B换成ViT-H。
SAM模型会做出分割来辅助人工标注。由于模型不断精确，标注时间也在降低.

2.SAM半自动标注
这一阶段在于增加模型的多样性，标注次突出的物体。首先让模型标注一部分，然后人工标注没有被模型标注的部分。大部分都被模型标出来了，剩下的是更难分割的物体。

3.全自动标注
经过第一阶段，训练集多了，模型准确率有所提升，也有了mask的多样性。
第2阶段解决了提示信息有歧义情况下的预测。
现在，给模型提示32x32的grid，每个点都要对有效目标预测一系列的mask.
然后用IOU阈值选择confident masks. 最后用NMS滤掉多余的mask.

## 模型结构

![](./assets/model_diagram.png)

如图，该模型的网络结构主要分三个部分：Image encoder、Prompt encoder和Lightweight mask decoder。
### Image encoder
通常，Image encoder可以是输出C×H×W图像嵌入的任何网络。受可扩展性和强大的预训练的启发，使用MAE预训练的视觉转换器（ViT），具有最小的适应性来处理高分辨率输入，特别是具有14×14窗口注意力和四个等距全局注意力块的ViT-H/16。图像编码器的输出是输入图像的16倍缩小的嵌入。使用1024×1024的输入分辨率，该分辨率是通过重新缩放图像并填充短边获得的。因此，图像嵌入是64×64。为了降低通道维度，使用1×1卷积来获得256个通道，然后使用3×3卷积来获得同样具有256个通道的通道。

### Prompt encoder 
按如下方式映射到256维向量嵌入中。一个点由其位置的位置编码的总和以及两个学习的嵌入之一表示，指示该点是在前景还是背景中。一个框由一个嵌入对表示：(1)其左上角的位置编码与表示“左上角”的学习嵌入相加。(2)相同的结构，但使用表示“右下角”的学习嵌入。最后，为了表示自由形式的文本，使用CLIP中的文本编码器（通常任何文本编码器都可以）。密集提示（即掩码）与图像具有空间对应关系。我们以比输入图像低4倍的分辨率输入掩码，然后使用两个2×2、步幅2(convolutions)进行降采样，输出通道分别为4和16。最后，1×1卷积将通道维度映射到256个维度。每层之间通过GELU激活和层归一化分开。然后将掩码嵌入和图像嵌入逐元素相加。如果没有掩码提示，则添加表示“无掩码”的学习嵌入到每个图像嵌入位置。

### Lightweight mask decoder 
![](./assets/mask_decoder.PNG)

解码器设计如图所示。使用两个转置卷积层将更新的图像嵌入放大4倍（现在相对于输入图像缩小了4倍）。将更新的输出token嵌入传递给一个小的3层MLP，它输出一个与扩展的图像嵌入的通道维度匹配的向量。最后，使用扩展的图像嵌入和MLP的输出进行空间点乘，预测出一个掩码。Transformer使用256的嵌入维度。在64×64图像嵌入的交叉注视层中，查询、键和值通道维度为128。所有注意力层都使用8个头。用于放大输出图像嵌入的转置卷积是2×2，步幅2，输出通道维度为64和32，并具有GELU激活。它们通过层归一化来分隔。

## 数据集
本项目的测试数据集为项目同级目录下的datasets文件夹，里面具有测试样例。

完整数据集可在[这里](https://ai.facebook.com/datasets/segment-anything-downloads/)进行下载

## Segment Anything掩码生成
注：官网提供了生成掩码的预训练权重和生成掩码的脚本（没有提供训练脚本）。

### 环境配置
从[光源](https://www.sourcefind.cn/#/service-list)拉取镜像
```
docker pull image.sourcefind.cn:5000/dcu/admin/base/pytorch:1.10.0-centos7.6-dtk-22.10-py39-latest
```
安装其他依赖：
```
pip install opencv-python pycocotools matplotlib onnxruntime onnx
```

### 掩码生成指令

```
python scripts/amg.py --checkpoint <path/to/checkpoint> --model-type <model_type> --input <image_or_folder> --output <path/to/output>
```
注：checkpoint预训练模型在[这里](https://github.com/search?q=segment-anything&type=repositories#model-checkpoints)下载

指令中：<path/to/checkpoint> 代表选择权重的路径

<model_type> 代表不同的模型，可选择'vit_h'、'vit_l'、 'vit_b'

<image_or_folder> 代表输入图片或者文件夹的路径

<path/to/output> 代表分割结果保存路径


### 掩码生成结果
掩码生成的部分结果在同级目录outputs中可以查看
官方提供demo可在[这里](https://segment-anything.com/demo)试用

## 参考

https://github.com/facebookresearch/segment-anything

















