指南 3个标注团队操作手册:提升标注速度与质量

在Label Studio中使用Segment Anything模型进行交互式标注

https://github.com/shondle/label-studio-ml-backend/assets/106922533/42a8a535-167c-404a-96bd-c2e2382df99a

在Label Studio中使用Facebook的Segment Anything模型! 2024年7月,Facebook发布了Segment Anything模型的更新版本,称为SAM 2。要使用这个新版本进行标注,请参阅segment_anything_2_image仓库

开始之前

在开始之前,您必须安装Label Studio ML后端

本教程使用segment_anything_model示例

快速入门

要启动带有轻量级移动版SAM的服务器,请运行以下命令:

docker-compose up

GPU支持

默认情况下,docker-compose文件会在CPU上运行模型。如果您拥有GPU,可以通过在docker-compose.yml中添加以下行来启用它:

environment:
  - NVIDIA_VISIBLE_DEVICES=all
deploy:
  reservations:
    devices:
      - driver: nvidia
        count: 1
        capabilities: [gpu]

关于模型

此代码库中有两个模型可供使用:

  1. 高级Segment Anything模型
  2. ONNX 分段任意模型

高级 Segment Anything 模型

高级Segment Anything模型引入了结合多种不同提示以实现预测的能力,以及使用MobileSAM的能力。

  • 将一个矩形标签与多个正关键点混合,以优化您的预测结果。
  • 使用负关键点从预测中移除区域,以增强控制。
  • 使用MobileSAM,这是一个极其轻量级的替代方案,可替代Facebook庞大的Segment Anything Model来获取预测结果。仅需笔记本电脑GPU即可在一秒内完成推理。

ONNX 分段任意模型

ONNX Segment Anything 模型让您能够使用单个关键点或单个矩形标签来提示原始 SAM。

  • 相比使用原始Segment Anything模型,这提供了更快的预测速度。
  • 缺点是使用ONNX模型之前必须指定图像尺寸,且在标注过程中无法泛化到其他图像尺寸。此外,目前还不支持像AdvancedSAM那样的混合标注与精修功能。

模型配置选项

每个模型都有不同的优缺点。请根据您的项目需求选择最适合的:

  • 高级SAM

    • Mobile SAM Configuration
      • 优点:轻量级模型,可在笔记本电脑上运行,并能混合多种不同的输入提示组合来微调预测。
      • 缺点:准确度低于Facebook原生的SAM架构。
    • Original SAM architecture
      • 优点:比MobileSAM更高的准确度,能够混合多种不同的输入提示组合来微调预测。
      • 缺点:收集预测结果耗时较长(生成一张图片的嵌入向量约需2秒),且需要配备高性能GPU。
  • ONNXSAM

    • Original SAM Architecture
      • 优点:比在Advanced SAM中使用时快得多。
      • 缺点:每个预测只能使用一个智能标签。在生成ONNX模型前必须定义图像尺寸。如果标注不同尺寸的图像会遇到问题。

设置

如果为项目启用了本地存储,Label Studio SAM后端能发挥最佳性能。虽然也可以设置共享本地存储,但不建议这样做。目前,该后端不支持云存储(S3、Azure、GCP)。

设置Label Studio服务器

启用本地存储文件服务

您可以通过设置以下变量来启用本地存储文件服务:

LABEL_STUDIO_LOCAL_FILES_DOCUMENT_ROOT=<path_to_image_data>
LABEL_STUDIO_LOCAL_FILES_SERVING_ENABLED=true

例如,如果您正在使用Docker启动Label Studio,可以通过以下方式启用这些变量

docker run -it -p 8080:8080 \
               -v $(pwd)/mydata:/label-studio/data \
               --env LABEL_STUDIO_LOCAL_FILES_SERVING_ENABLED=true \
               --env LABEL_STUDIO_LOCAL_FILES_DOCUMENT_ROOT=/label-studio/data/images \
               heartexlabs/label-studio:latest

请注意运行Label Studio实例的IP地址作为LABEL_STUDIO_HOST。这对于建立与SAM模型的连接是必需的。

由于您同时在Docker容器中运行Label Studio和ML后端服务,主机名localhost将无法解析到正确的地址。 有几种方法可以确定您的主机IP地址。这些方法包括在命令行中执行ip aifconfig命令并检查输出结果,或者通过系统网络配置设置查找分配给计算机的地址。

获取您的API令牌

登录Label Studio界面(在上面的示例中,地址为 http://:8080)。

前往账户与设置页面,记录下访问令牌,我们稍后将使用它作为LABEL_STUDIO_ACCESS_TOKEN

配置SAM后端

克隆仓库

在您的主机系统上克隆此仓库,并将其移动到工作目录中。

git clone https://github.com/humansignal/label-studio-ml-backend
cd label-studio-ml-backend/label_studio_ml/examples/segment_anything_model

我们建议使用Docker Compose来托管和运行后端。如需GPU支持,请参考Docker Compose GPU访问指南了解如何将GPU资源透传给服务。

编辑docker-compose.yml文件并填写您特定安装的LABEL_STUDIO_HOSTLABEL_STUDIO_ACCESS_TOKEN变量值。请确保在LABEL_STUDIO_HOST变量中附加Label Studio运行的端口号,例如如果Label Studio运行在8080端口上,则填写http://192.168.1.36:8080

运行命令 docker compose up --build 来构建容器并在本地运行。

手动设置后端

下载模型权重

仅当您未使用此模型的Docker构建时,才需要执行此步骤。

  • 对于MobileSAM,请使用此链接安装权重文件,并将其放置在一个文件夹中(与advanced_sam.py和onnx_sam.py文件放在一起)

  • 要使用常规SAM和/或ONNX- 请按照SAM的pip安装说明进行操作。然后安装ViT-H SAM模型

  • 对于ONNX模型,使用python onnxconverter.py安装

您可以使用以下命令下载所有权重和模型:

./download_models.sh

安装要求

切换到该目录文件夹,然后安装所有Python依赖项。

pip install -r requirements.txt

根据您选择的模型调整变量和_wsgi.py

您可以设置以下环境变量来更改模型的行为。

  • LABEL_STUDIO_HOST 设置Label Studio主机的终端节点。必须以http://开头
  • LABEL_STUDIO_ACCESS_TOKEN 设置Label Studio主机的API访问令牌。
  • SAM_CHOICE selects which model to use.
    • SAM_CHOICE=MobileSAM 使用MobileSAM(默认)
    • SAM_CHOICE=SAM 使用原始SAM模型。
    • SAM_CHOICE=ONNX 使用ONNX模型。

启动后端服务

您现在可以手动启动ML后端。

python _wsgi.py

docker-compose up

在Docker容器中启动后端

MOBILESAM_CHECKPOINT=path/to/mobile_sam.pt label-studio-ml start segment_anything_model/

注意:如果在MacOS上看到错误,请尝试设置环境变量 KMP_DUPLICATE_LIB_OK=True

在Label Studio中为Segment Anything设置项目

登录您的Label Studio实例并执行以下步骤。

  1. 创建一个新项目。

  2. 在创建项目时的标注设置步骤中,或在项目设置的标注界面下,将示例模板粘贴到代码对话框中。保存界面。

  3. 前往项目设置中的模型页面,点击连接模型

  4. 输入模型的标题,以及您刚创建的模型实例的URL。

    如果您在Docker或其他主机上运行Label Studio,应使用模型所在主机的直接IP地址(localhost将不起作用)。请确保包含模型运行的端口号(默认为9090)。例如,如果模型托管在192.168.1.36上,模型的URL应为http://192.168.1.36:9090

  5. 点击验证并保存

您现在可以将图片上传到项目中并开始标注。

The video 视频中也演示了这个流程,但部分操作是在新创建的项目菜单中完成的。

创建标注

观看此视频教程以更好地理解使用SAM进行标注时的工作流程。

使用Alt快捷键来切换关键点的正负标签。

AdvancedSAM 使用说明

  • 请先观看此视频

  • 为了获得最佳体验,请按照上方视频教程操作,并在运行预测时取消勾选'自动接受标注建议'

  • 从各种输入生成预测后,请确保点击图像外部的对勾标记以确认区域(该标记通常位于图像上方或下方。观看视频获取可视化指引)。

  • 生成的预测旁边图像内部可能有一个勾选标记,但不要使用那个

    由于某些原因,不在图像本身的勾选标记会清除用于生成区域的其他输入提示,点击后仅保留预测区域(这是与后端最兼容的使用方式)。

  • 如果在图像上点击勾选框时,标签离开了用于引导区域的标记,您可能会遇到创建同一类实例的问题。

  • 标注完对象后,在菜单中选择标签,并在图像下方的标签键顶部选择要赋予的笔刷标签类型。这允许您更改预测类别。观看视频获取更详细的说明。

  • 只有负向关键点可用于从预测区域中减去模型。正向关键点和矩形框指示模型需要关注以做出正向预测的区域。

  • 可以使用多个关键点为模型提供需要扩展预测的区域。在生成预测时只能使用一个矩形标签,作为模型预测应该出现/扩展的区域。

    如果放置多个矩形标签,模型在辅助预测时将使用最新的矩形标签以及所有其他关键点。

ONNX 使用说明

  • ONNX模型使用onnx_converter.py中的orig_img_size参数来定义模型的图像比例。在生成模型前,请将此值调整为待标注图像的实际比例。如果您需要标注不同尺寸的图像,请改用Advanced SAM,或为不同尺寸的图像组分别生成新的ONNX模型。若未调整orig_img_size且图像宽高比与预设值不匹配,预测结果将会出现位置偏移。若使用docker compose启动模型,请务必重新构建宿主容器。
  • 在使用onnx_converter.py时,请确保在生成ONNX模型前调整好orig_img_size参数
  • 修改代码指南 - "orig_im_size": torch.tensor([#heightofimages, #widthofimages], dtype=torch.float),

导出注意事项

  • 不支持COCO和YOLO格式(本项目使用笔刷标签导出,请尝试改用NumPy或PNG格式导出)

标注配置

使用AdvancedSAM时

  • 为每个需要标注的类别提供一个笔刷标签。
  • 按住Alt快捷键可创建负关键点。
  • 为您想要标注的每个类别添加一个矩形标签。
  • The video 如果你在阅读后感到困惑,视频也会回顾这些要点。

基础示例:

<View>
<Style>
  .main {
    font-family: Arial, sans-serif;
    background-color: #f5f5f5;
    margin: 0;
    padding: 40px 5px 5px 5px;
  }
  .container {
    display: flex;
    justify-content: space-between;
    margin-bottom: 20px;
  }
  .column {
    flex: 1;
    padding: 10px;
    margin: 5px; 
    background-color: #fff;
    border-radius: 5px;
    box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
    text-align: center;
  }
  .column .title {
    margin: 0;
    color: #333;
  }
  .column .label {
    margin-top: 10px;
    padding: 10px;
    padding-bottom: 7px; 
    background-color: #f9f9f9;
    border-radius: 3px;
  }
  .lsf-labels {
    margin: 5px 0 0 0; 
  }
  .image-container {
    width: 100%;
    height: 300px;
    background-color: #ddd;
    border-radius: 5px;
  }
</Style>
  
<View className="main">
  <View className="container">
    <View className="column">
      <HyperText value="" name="h1" className="help" inline="true">
        Brush for manual labeling
      </HyperText>
      <View className="label">        
        <BrushLabels name="tag" toName="image">
          <Label value="Foreground" background="#FF0000" />
          <Label value="Background" background="#0d14d3" />
        </BrushLabels>
      </View>
    </View>
    
    <View className="column">
      <HyperText value="" name="h2" className="help" inline="true">
        <span title="1. Click purple auto Keypoints/Rectangle icon on toolbar. 2. Click Foreground/Background label here">
          Keypoints for auto-labeling
        </span>
      </HyperText>
      <View className="label">
        <KeyPointLabels name="tag2" toName="image" smart="true">
          <Label value="Foreground" smart="true" background="#FFaa00" showInline="true" />
          <Label value="Background" smart="true" background="#00aaFF" showInline="true" />
        </KeyPointLabels>
      </View>
    </View>
    
    <View className="column">
      <HyperText value="" name="h3" className="help" inline="true">
        <span title="1. Click purple auto Keypoints/Rectangle icon on toolbar. 2. Click Foreground/Background label here">
          Rectangles for auto-labeling
        </span>
      </HyperText>
      <View className="label">
        <RectangleLabels name="tag3" toName="image" smart="true">
          <Label value="Foreground" background="#FF00FF" showInline="true" />
          <Label value="Background" background="#00FF00" showInline="true" />
        </RectangleLabels>
      </View>
    </View>
    
  </View>
  
  <View className="image-container">
    <Image name="image" value="$image" zoom="true" zoomControl="true" />
  </View>
  
</View>
</View>

使用ONNX模型时

关键点、矩形和笔刷标签的标注值必须相互对应。除此之外,请确保每个关键点标签和矩形标签都设置smart="True"

对于ONNX模型:

<View>
  <Image name="image" value="$image" zoom="true"/>
  <BrushLabels name="tag" toName="image">
    <Label value="Banana" background="#FF0000"/>
    <Label value="Orange" background="#0d14d3"/>
  </BrushLabels>
  <KeyPointLabels name="tag2" toName="image" smart="true">
    <Label value="Banana" smart="true" background="#000000" showInline="true"/>
    <Label value="Orange" smart="true" background="#000000" showInline="true"/>
  </KeyPointLabels>
  <RectangleLabels name="tag3" toName="image" smart="true">
    <Label value="Banana" background="#000000" showInline="true"/>
    <Label value="Orange" background="#000000" showInline="true"/>
  </RectangleLabels>
</View>

致谢

原始Segment Anything模型论文-

@article{kirillov2023segany,
  title={Segment Anything},
  author={Kirillov, Alexander and Mintun, Eric and Ravi, Nikhila and Mao, Hanzi and Rolland, Chloe and Gustafson, Laura and Xiao, Tete and Whitehead, Spencer and Berg, Alexander C. and Lo, Wan-Yen and Doll{\'a}r, Piotr and Girshick, Ross},
  journal={arXiv:2304.02643},
  year={2023}
}

MobileSAM论文-

@article{mobile_sam,
  title={Faster Segment Anything: Towards Lightweight SAM for Mobile Applications},
  author={Zhang, Chaoning and Han, Dongshen and Qiao, Yu and Kim, Jung Uk and Bae, Sung-Ho and Lee, Seungkyu and Hong, Choong Seon},
  journal={arXiv preprint arXiv:2306.14289},
  year={2023}
}