X-AnyLabeling 应用和 YOLO 实战教程

X-AnyLabeling 应用和 YOLO 实战教程

本教程将详细介绍如何使用 X-AnyLabeling 进行图像标注,并使用 YOLO 进行模型训练。

1. X-AnyLabeling 的安装

1.1 环境要求

  • Conda 创建专门的环境
  • Git(用于克隆源代码)
  • pip 包管理器
conda create -n label -y # 不需要指定 python 的版本号
conda activate label

1.2 从源代码安装

步骤 1:克隆仓库

# git clone https://github.com/vietanhdev/anylabeling.git
# cd anylabeling
git clone https://github.com/CVHub520/X-AnyLabeling
cd X-AnyLabeling

步骤 2:安装依赖

# 安装基础依赖
pip install -r requirements.txt

# 如果需要 GPU 支持(推荐)
pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118

步骤 3:运行应用

python3 anylabeling/app.py

1.3 验证安装

启动应用后,如果看到图形界面窗口,说明安装成功。

2. X-AnyLabeling 页面操作的简单说明

2.1 主界面布局

X-AnyLabeling 的主界面包含以下主要区域:

  • 左侧工具栏:标注工具(矩形、多边形、点等)
  • 中央画布:显示当前图像和标注
  • 右侧面板:标签管理和属性设置
  • 底部状态栏:显示当前操作状态

2.2 基本操作

下一张图片
  • 快捷键D(下一张),A(上一张),F (完成当前图片标注)
  • 菜单操作FileNext Image / Previous Image
  • 按钮:点击工具栏中的前进/后退按钮
Label 管理
  1. 创建标签

    • 点击右侧面板的 + 按钮
    • 输入标签名称(如:person, car, dog
    • 选择标签颜色(可选)
  2. 编辑标签

    • 右键点击标签列表中的标签
    • 选择 Edit 进行修改
    • 可以修改名称、颜色等属性
  3. 删除标签

    • 右键点击标签,选择 Delete
    • 或选中标签后按 Delete
进行标注
  1. 矩形标注(Bounding Box)

    • 选择矩形工具(快捷键 R
    • 在图像上拖拽绘制矩形框
    • 选择对应的标签
  2. 多边形标注(Polygon/Segmentation)

    • 选择多边形工具(快捷键 P
    • 点击图像上的点创建多边形顶点
    • 双击完成多边形绘制
    • 选择对应的标签
  3. 编辑标注

    • 点击已存在的标注框/多边形
    • 拖拽顶点调整形状
    • 右键菜单可以删除或修改属性
AI 辅助标注及位置
  1. 启用 AI 辅助

    • 点击工具栏中的 AI 按钮,在左边的侧边栏,图标是一个圆圈包裹 AI 两个字母。
    • 或使用快捷键 Ctrl + A
  2. AI 辅助标注位置

    • 自动标注:AI 会自动检测图像中的物体并生成标注框
    • 智能建议:在手动标注时,AI 会提供标注建议
    • 快速标注:批量处理多张图像
  3. AI 模型选择

    • SettingsAI Model 中选择不同的 AI 模型
    • 支持 YOLO、SAM(Segment Anything Model)等模型

3. AI 辅助标注工具的下载

一开始没有任何模型,会提示没有可用模型,这个时候只需要手动添加就可以了,选择的是 meta 下面的 Segment Anything (ViT-base quant),点击之后就会自动下载了,下载完毕之后选择使用,就会提供一些工具;点击这些工具进行使用,例如 点工具 只需要在感兴趣的地方点一下就可以自动分割,会自动计算出一个矩形框,这个时候如果没有问题就按 f 键,弹出标注框,设置标签即可。

3.1 操作流程

  1. 打开设置

    • 点击菜单 SettingsAI Model Settings
    • 或使用快捷键 Ctrl + ,
  2. 选择模型

    • 在模型列表中选择需要的模型(如:YOLOv8、SAM、RT-DETR 等)
    • 点击 Download 按钮
  3. 等待下载

    • 下载进度会显示在状态栏
    • 模型文件较大,可能需要几分钟
  4. 验证下载

    • 下载完成后,模型会出现在已安装模型列表中
    • 可以点击 Test 按钮测试模型

3.2 下载的位置

模型文件默认保存在以下位置:

Linux/Mac

~/.xanylabeling_data/models/

手动指定位置

  • 在设置中可以修改模型保存路径
  • SettingsGeneralModel Directory

3.3 常用 AI 模型

  • YOLOv8:目标检测,速度快,精度高
  • SAM (Segment Anything):图像分割,支持零样本分割
  • RT-DETR:实时目标检测
  • YOLOv5:经典目标检测模型

4. 标记图片并导出成 YOLO Segment 格式

4.1 使用 AI 工具完成标注任务

最开始的步骤一定是准备图片,然后将这些图片规范命名,放在一个单独的文件夹下面,加载到 X-Labeling 工作空间中,这一步是开始,也是最重要的一步。

  1. 准备图像

    • 将需要标注的图像放在一个文件夹中
    • 支持的格式:.jpg, .png, .bmp
  2. 加载图像

    • FileOpen Dir 选择图像文件夹
    • FileOpen 打开单张图像
  3. 使用 AI 辅助标注

    • 点击 AI 按钮启用 AI 辅助
    • 选择 AI 模型(如 Meta 的 Vit-base Quant)
    • AI 会自动检测并标注物体
    • 手动调整不准确的标注
  4. 手动补充标注

    • 对于 AI 未检测到的物体,手动添加标注
    • 使用多边形工具进行精确分割标注

4.2 YOLO Segment 格式介绍

YOLO Segment 格式用于实例分割任务,包含以下内容:

目录结构

dataset/
├── images/
│   ├── train/
│   │   ├── image1.jpg
│   │   └── image2.jpg
│   └── val/
│       └── image3.jpg
└── labels/
    ├── train/
    │   ├── image1.txt
    │   └── image2.txt
    └── val/
        └── image3.txt

标签文件格式(.txt)

class_id x1 y1 x2 y2 x3 y3 ... xn yn
  • class_id:类别ID(从0开始)
  • x1 y1 x2 y2 ...:归一化的多边形顶点坐标(0-1之间)
  • 每个顶点用两个浮点数表示(x, y)
  • 一行表示一个实例

示例

0 0.5 0.3 0.7 0.3 0.7 0.6 0.5 0.6
1 0.2 0.1 0.4 0.1 0.4 0.3 0.2 0.3

4.2节有点迷惑性,事实上不应该出现在文章的这个位置,因为这和数据的标注毫无联系,应该跳过 4.2 节,等到后续导出标注完成之后再按照 4.2 节的格式整理数据集。实际上这里和 5.1 有些重复了。

4.3 导出标注

  1. 设置导出格式

    • FileExport Annotations
    • 选择 YOLO 格式
    • 选择 Segment 模式(分割模式)
  2. 选择导出选项

    • 选择保存路径
    • 选择是否包含图像(复制图像到导出目录)
    • 选择是否分离训练集和验证集
  3. 导出

    • 点击 Export 按钮
    • 导出的内容会覆盖原来同名文件夹中的所有内容,在导出的时候同时勾选出将原始图片一起导出,这样有利于后面训练数据集的构建。
    • 等待导出完成

5. 将图片和标签整理成标准训练目录 Dataset

一般来说在 ~/ 下创建一个名为 dataset 的目录作为训练数据集的根目录。

5.1 标准 YOLO 训练目录结构

将上一小节导出的内容整理成如下形式:

dataset/
├── images/
│   ├── train/          # 训练图像
│   │   ├── img1.jpg
│   │   └── img2.jpg
│   └── val/            # 验证图像
│       └── img3.jpg
└── labels/
    ├── train/          # 训练标签
    │   ├── img1.txt
    │   └── img2.txt
    └── val/            # 验证标签
        └── img3.txt

5.2 格式转换脚本(手动整理也是可以的)

创建 convert_to_yolo_dataset.py

import os
import shutil
from pathlib import Path
import random

def convert_to_yolo_dataset(
    source_dir,
    output_dir,
    train_ratio=0.8,
    val_ratio=0.2
):
    """
    将 X-AnyLabeling 导出的 YOLO 格式转换为标准训练目录结构
    
    Args:
        source_dir: 源目录(包含 images 和 labels 文件夹)
        output_dir: 输出目录
        train_ratio: 训练集比例
        val_ratio: 验证集比例
    """
    source_path = Path(source_dir)
    output_path = Path(output_dir)
    
    # 创建输出目录结构
    (output_path / "images" / "train").mkdir(parents=True, exist_ok=True)
    (output_path / "images" / "val").mkdir(parents=True, exist_ok=True)
    (output_path / "labels" / "train").mkdir(parents=True, exist_ok=True)
    (output_path / "labels" / "val").mkdir(parents=True, exist_ok=True)
    
    # 获取所有图像文件
    if (source_path / "images").exists():
        images_dir = source_path / "images"
    else:
        images_dir = source_path
    
    image_files = list(images_dir.glob("*.jpg")) + \
                  list(images_dir.glob("*.png")) + \
                  list(images_dir.glob("*.jpeg"))
    
    # 随机打乱
    random.shuffle(image_files)
    
    # 计算分割点
    total = len(image_files)
    train_count = int(total * train_ratio)
    
    # 分割数据集
    train_images = image_files[:train_count]
    val_images = image_files[train_count:]
    
    # 复制文件
    labels_dir = source_path / "labels" if (source_path / "labels").exists() else source_path
    
    for img_path in train_images:
        # 复制图像
        shutil.copy2(img_path, output_path / "images" / "train" / img_path.name)
        
        # 复制标签
        label_path = labels_dir / f"{img_path.stem}.txt"
        if label_path.exists():
            shutil.copy2(label_path, output_path / "labels" / "train" / label_path.name)
    
    for img_path in val_images:
        # 复制图像
        shutil.copy2(img_path, output_path / "images" / "val" / img_path.name)
        
        # 复制标签
        label_path = labels_dir / f"{img_path.stem}.txt"
        if label_path.exists():
            shutil.copy2(label_path, output_path / "labels" / "val" / label_path.name)
    
    print(f"转换完成!")
    print(f"训练集: {len(train_images)} 张图像")
    print(f"验证集: {len(val_images)} 张图像")

if __name__ == "__main__":
    # 使用示例
    convert_to_yolo_dataset(
        source_dir="./exported_data",  # X-AnyLabeling 导出的目录
        output_dir="./dataset",        # 输出目录
        train_ratio=0.8,
        val_ratio=0.2
    )

使用方法

python convert_to_yolo_dataset.py

5.3 实践中的 dataset 结构

.
├── data.yaml
├── images
│   ├── train
│   │   ├── 微信图片_20251128132525_22.jpg
│   │   ├── 微信图片_20251128132550_23.jpg
│   │   ├── 微信图片_20251128132555_24.jpg
│   │   ├── 微信图片_20251128132558_25.jpg
│   │   ├── 微信图片_20251128132600_26.jpg
│   │   ├── 微信图片_20251128132603_27.jpg
│   │   ├── 微信图片_20251128132605_28.jpg
│   │   ├── 微信图片_20251128132607_29.jpg
│   │   ├── 微信图片_20251128132610_29.jpg
│   │   ├── 微信图片_20251128132637_38.jpg
│   │   ├── 微信图片_20251128132641_39.jpg
│   │   ├── 微信图片_20251128132644_40.jpg
│   │   ├── 微信图片_20251128132647_41.jpg
│   │   ├── 微信图片_20251128132649_42.jpg
│   │   ├── 微信图片_20251128132653_43.jpg
│   │   ├── 微信图片_20251128132655_44.jpg
│   │   └── 微信图片_20251128132700_45.jpg
│   └── val
│       ├── 微信图片_20251128132613_30.jpg
│       ├── 微信图片_20251128132617_31.jpg
│       ├── 微信图片_20251128132702_46.jpg
│       └── 微信图片_20251128132705_47.jpg
└── labels
    ├── train
    │   ├── 微信图片_20251128132525_22.txt
    │   ├── 微信图片_20251128132550_23.txt
    │   ├── 微信图片_20251128132555_24.txt
    │   ├── 微信图片_20251128132558_25.txt
    │   ├── 微信图片_20251128132600_26.txt
    │   ├── 微信图片_20251128132603_27.txt
    │   ├── 微信图片_20251128132605_28.txt
    │   ├── 微信图片_20251128132607_29.txt
    │   ├── 微信图片_20251128132637_38.txt
    │   ├── 微信图片_20251128132641_39.txt
    │   ├── 微信图片_20251128132644_40.txt
    │   ├── 微信图片_20251128132647_41.txt
    │   ├── 微信图片_20251128132649_42.txt
    │   ├── 微信图片_20251128132653_43.txt
    │   ├── 微信图片_20251128132655_44.txt
    │   └── 微信图片_20251128132700_45.txt
    ├── val
    │   ├── 微信图片_20251128132613_30.txt
    │   ├── 微信图片_20251128132617_31.txt
    │   ├── 微信图片_20251128132702_46.txt
    │   └── 微信图片_20251128132705_47.txt
    └── val.cache

6 directories, 44 files

6. 为 Dataset 写一个 data.yaml

6.1 data.yaml 格式说明

data.yaml 是 YOLO 训练所需的配置文件,定义了数据集路径、类别等信息。

6.2 标准格式示例

创建 data.yaml

# 数据集路径(相对于此 yaml 文件的路径)
path: ./dataset  # 数据集根目录
train: images/train  # 训练图像路径(相对于 path)
val: images/val      # 验证图像路径(相对于 path)

# 类别数量
nc: 3  # number of classes

# 类别名称列表
names:
  0: person    # 类别 0 的名称
  1: car       # 类别 1 的名称
  2: dog       # 类别 2 的名称

6.3 完整示例

# YOLO Dataset Configuration
# 数据集配置文件

# 数据集根目录路径
path: /path/to/your/dataset

# 训练和验证数据路径(相对于 path)
train: images/train
val: images/val

# 测试集(可选)
# test: images/test

# 类别数量
nc: 5

# 类别名称(必须与标注文件中的 class_id 对应)
names:
  0: person
  1: bicycle
  2: car
  3: motorcycle
  4: bus

# 下载脚本(可选,用于自动下载数据集)
# download: |
#   python download.py

6.4 注意事项

  1. 路径设置

    • 可以使用绝对路径或相对路径
    • 相对路径是相对于 data.yaml 文件的位置
    • 确保路径正确,否则训练时会报错
  2. 类别ID对应

    • names 中的索引必须与标注文件中的 class_id 对应
    • 类别ID从 0 开始
    • 类别数量 nc 必须等于 names 的长度
  3. 文件结构

    • 确保 images/trainimages/val 目录存在
    • 确保 labels/trainlabels/val 目录存在
    • 图像和标签文件名必须一一对应(扩展名不同)
  4. 验证配置

    • 可以使用 YOLO 的验证脚本检查配置是否正确
    • 确保所有路径可访问

6.5 实践中的 data.yaml

# custom_data.yaml
path: /home/ubuntu/dataset  # 数据集根目录

# 图像路径
train: images/train
val: images/val
# test: images/test  # 可选

# 类别信息
nc: 2
names:
  0: 'coffee'
  1: 'coke'

# 下载命令/URL(可选)
# download: https://ultralytics.com/assets/coco128.zip           

7. 使用 Python 命令下载训练所需模型权重

7.1 YOLOv8 模型下载

X-AnyLabeling 不直接提供模型权重下载服务,需要手动下载或使用脚本下载。

方法 1:使用 ultralytics 库下载

from ultralytics import YOLO

# 下载预训练模型
model = YOLO('yolov8n-seg.pt')  # nano 版本,分割模型
# 可选模型:
# - yolov8n-seg.pt (nano, 最小最快)
# - yolov8s-seg.pt (small)
# - yolov8m-seg.pt (medium)
# - yolov8l-seg.pt (large)
# - yolov8x-seg.pt (xlarge, 最大最准确)
python3 -C "from ultralytics import YOLO; model = YOLO('yolov8n-seg.pt')  # nano 版本,分割模型"

方法 2:手动下载

访问 Ultralytics 官方仓库 下载权重文件。

7.2 权重文件保存位置

默认位置

# Linux/Mac
~/.ultralytics/weights/

X-AnyLabeling 模型位置

# Windows
C:\Users\<用户名>\.anylabeling\models\

# Linux/Mac
~/.anylabeling/models/

7.3 下载脚本示例

创建 download_weights.py

from ultralytics import YOLO
import os

def download_yolo_weights(model_name='yolov8n-seg.pt', save_dir=None):
    """
    下载 YOLO 模型权重
    
    Args:
        model_name: 模型名称
        save_dir: 保存目录(如果为 None,使用默认位置)
    """
    # 创建保存目录
    if save_dir:
        os.makedirs(save_dir, exist_ok=True)
        save_path = os.path.join(save_dir, model_name)
    else:
        save_path = None
    
    # 下载模型
    model = YOLO(model_name)
    
    if save_path:
        # 复制到指定位置
        import shutil
        default_path = model.ckpt_path
        shutil.copy2(default_path, save_path)
        print(f"模型已保存到: {save_path}")
    else:
        print(f"模型已下载到默认位置: {model.ckpt_path}")
    
    return model.ckpt_path

if __name__ == "__main__":
    # 下载不同大小的模型
    models = [
        'yolov8n-seg.pt',  # nano
        'yolov8s-seg.pt',  # small
        'yolov8m-seg.pt',  # medium
    ]
    
    for model_name in models:
        print(f"正在下载 {model_name}...")
        download_yolo_weights(model_name)
        print(f"{model_name} 下载完成\n")

运行脚本

pip install ultralytics
python download_weights.py

注意事项

  • 模型文件较大(几十MB到几百MB),需要稳定的网络连接
  • 下载后的权重文件可以复制到 X-AnyLabeling 的模型目录使用
  • 确保有足够的磁盘空间

7.4 实际上使用的方法

上面几种方法都可以下载到对应的 pt 文件,但是在上一次成功的经验中,我是将 Ultralytics 的源代码下载了下来,然后使用脚本指令的方式下载想要的 pt 文件,这样下载下来的 pt 文件就直接放在了 Ultralytics 源代码的根目录下面了。

# 1. 克隆Ultralytics仓库
git clone https://github.com/ultralytics/ultralytics.git

# 2. 进入目录
cd ultralytics

# 3. 安装依赖
pip install -e .

# 4. 用Python脚本下载pt文件(直接下载到当前目录)
python -c "from ultralytics import YOLO; model = YOLO('yolov8n.pt')"

# 或者下载特定模型
python -c "from ultralytics import YOLO; YOLO('yolov8s-seg.pt')"  # 分割模型

8. 在 X-AnyLabeling 中训练模型

8.1 准备工作

  1. 确保数据集已准备好

    • 数据集目录结构正确
    • data.yaml 配置文件已创建;(据上所述,我的 data.yaml 是放在 ~/dataset 中的
    • 图像和标签文件一一对应)
  2. 选择预训练模型

    • 选择 Ultralytics 源码根目录中通过指令下载得到的,名为 yolov8n.pt 的权重。

8.2 训练步骤

步骤 1:打开训练界面
  1. 点击菜单 ToolsTrain Model
  2. 或使用快捷键 Ctrl + T
  3. 训练界面会弹出
步骤 2:配置训练参数

在训练界面中设置以下参数:

基本设置

  • Model Type:选择 YOLOv8 Segment(分割模型)
  • Model Size:选择模型大小(n/s/m/l/x)
    • n (nano):最小最快,适合快速实验
    • s (small):平衡速度和精度
    • m (medium):较好的精度
    • l (large):高精度
    • x (xlarge):最高精度,但最慢

数据集设置

  • Dataset Path:选择 data.yaml 文件的路径
  • Train/Val Split:如果数据集中未分离,可以设置比例(默认 0.8/0.2)

训练参数

  • Epochs:训练轮数(建议 100-300)
  • Batch Size:批次大小(根据GPU内存调整,如 8, 16, 32)
  • Image Size:输入图像尺寸(如 640, 1280)
  • Learning Rate:学习率(默认自动调整)
  • Device:选择训练设备(CPU/GPU)

高级设置

  • Patience:早停耐心值(如果验证损失不下降,提前停止)
  • Save Period:保存检查点的周期
  • Project Name:项目名称
  • Experiment Name:实验名称
步骤 3:开始训练
  1. 检查所有参数设置
  2. 点击 Start Training 按钮
  3. 训练过程会显示在日志窗口中
步骤 4:监控训练过程

训练过程中可以查看:

  • Loss 曲线:训练损失和验证损失
  • Metrics:mAP、精度、召回率等指标
  • 训练进度:当前 epoch、剩余时间等
  • GPU 使用率:如果使用 GPU 训练

8.3 训练界面说明

主要区域

  • 左侧面板:参数配置区域
  • 中央区域:训练日志和进度显示
  • 右侧面板:实时指标和图表
  • 底部状态栏:当前训练状态

快捷键

  • Ctrl + S:保存当前配置
  • Ctrl + P:暂停/继续训练
  • Ctrl + Q:停止训练

8.4 训练技巧

  1. 从小模型开始

    • 先用 yolov8n-seg.pt 快速验证流程
    • 确认无误后再使用大模型
  2. 调整批次大小

    • GPU 内存不足时减小 batch size
    • 可以尝试使用梯度累积
  3. 数据增强

    • data.yaml 中可以配置数据增强参数
    • 如翻转、旋转、缩放等
  4. 学习率调整

    • 如果损失不下降,可以降低学习率
    • 使用学习率调度器

9. 训练结果及转换成 ONNX 格式输出模型

9.1 训练结果位置

训练完成后,模型和结果保存在以下位置:

默认保存路径

# Linux/Mac
~/.xanylabeling_data/trainer/Ultralytics/runs/segment/exp/weights

目录结构

runs/segment/exp/
├── weights/
│   ├── best.pt          # 最佳模型权重(验证集上表现最好)
│   └── last.pt          # 最后一轮的模型权重
├── results.png          # 训练结果图表
├── confusion_matrix.png # 混淆矩阵
├── F1_curve.png         # F1 曲线
├── PR_curve.png         # 精确率-召回率曲线
├── args.yaml            # 训练参数配置
└── results.csv          # 训练指标 CSV 文件

9.2 模型评估

训练完成后,可以查看:

  1. 最佳模型weights/best.pt - 在验证集上表现最好的模型
  2. 训练曲线results.png - 损失和指标曲线
  3. 混淆矩阵confusion_matrix.png - 类别预测混淆情况
  4. PR 曲线PR_curve.png - 精确率-召回率曲线

9.3 转换为 ONNX 格式

ONNX(Open Neural Network Exchange)是一种开放的模型格式,可以在不同框架间转换和部署。

方法 1:在 X-AnyLabeling 中转换
  1. 打开导出界面

    • 训练完成后,在训练界面点击 Export 按钮
    • 或选择 ToolsExport Model
  2. 选择导出格式

    • 在格式列表中选择 ONNX
    • 选择要导出的模型(best.ptlast.pt
  3. 设置导出参数

    • Input Size:输入图像尺寸(如 640)
    • Dynamic:是否支持动态输入尺寸
    • Simplify:是否简化模型(推荐)
    • Opset Version:ONNX opset 版本(默认 12)
  4. 导出

    • 点击 Export 按钮
    • 等待转换完成
    • 转换后的 .onnx 文件会保存在模型目录中
方法 2:使用 Python 脚本转换

创建 export_to_onnx.py

from ultralytics import YOLO
import os

def export_to_onnx(model_path, output_path=None, imgsz=640, simplify=True):
    """
    将 YOLO 模型转换为 ONNX 格式
    
    Args:
        model_path: .pt 模型文件路径
        output_path: 输出 ONNX 文件路径(如果为 None,自动生成)
        imgsz: 输入图像尺寸
        simplify: 是否简化模型
    """
    # 加载模型
    model = YOLO(model_path)
    
    # 导出为 ONNX
    success = model.export(
        format='onnx',
        imgsz=imgsz,
        simplify=simplify,
        opset=12,  # ONNX opset 版本
        dynamic=False,  # 是否支持动态输入
    )
    
    if success:
        # 获取导出后的文件路径
        if output_path is None:
            output_path = model_path.replace('.pt', '.onnx')
        
        print(f"模型已成功导出为 ONNX 格式: {output_path}")
        return output_path
    else:
        print("导出失败")
        return None

if __name__ == "__main__":
    # 使用示例
    model_path = r"C:\Users\<用户名>\.anylabeling\runs\segment\exp\weights\best.pt"
    export_to_onnx(model_path)

运行脚本

python export_to_onnx.py

9.4 ONNX 模型验证

转换完成后,可以验证 ONNX 模型:

import onnx
import onnxruntime as ort
import numpy as np

# 加载 ONNX 模型
onnx_model = onnx.load("best.onnx")
onnx.checker.check_model(onnx_model)

# 创建推理会话
session = ort.InferenceSession("best.onnx")

# 获取输入输出信息
input_name = session.get_inputs()[0].name
output_names = [output.name for output in session.get_outputs()]

print(f"输入名称: {input_name}")
print(f"输出名称: {output_names}")

# 测试推理
dummy_input = np.random.randn(1, 3, 640, 640).astype(np.float32)
outputs = session.run(output_names, {input_name: dummy_input})
print("ONNX 模型验证成功!")

10. 保存的位置以及测试、推理脚本

10.1 模型保存位置总结

训练模型

# Linux/Mac
~/.xanylabeling_data/trainer/Ultralytics/runs/segment/exp/weights/
  ├── best.pt
  └── last.pt

导出的 ONNX 模型

# 会被保存在模型权重同一目录
<weights_dir>/best.onnx

10.2 测试脚本

创建 test_model.py

from ultralytics import YOLO
from pathlib import Path
import cv2
import numpy as np

def test_model(model_path, image_path, conf_threshold=0.25, save_dir=None):
    """
    测试训练好的模型
    
    Args:
        model_path: 模型文件路径(.pt 或 .onnx)
        image_path: 测试图像路径或目录
        conf_threshold: 置信度阈值
        save_dir: 结果保存目录
    """
    # 加载模型
    model = YOLO(model_path)
    
    # 如果是目录,处理所有图像
    image_path = Path(image_path)
    if image_path.is_dir():
        image_files = list(image_path.glob("*.jpg")) + \
                     list(image_path.glob("*.png"))
    else:
        image_files = [image_path]
    
    # 创建保存目录
    if save_dir:
        save_path = Path(save_dir)
        save_path.mkdir(parents=True, exist_ok=True)
    else:
        save_path = None
    
    # 处理每张图像
    for img_file in image_files:
        # 推理
        results = model.predict(
            source=str(img_file),
            conf=conf_threshold,
            save=True,
            save_dir=str(save_path) if save_path else None,
            show_labels=True,
            show_conf=True,
            line_width=2
        )
        
        # 打印结果
        for result in results:
            print(f"\n图像: {img_file.name}")
            print(f"检测到 {len(result.boxes)} 个目标")
            
            # 打印每个检测结果
            for i, box in enumerate(result.boxes):
                cls = int(box.cls[0])
                conf = float(box.conf[0])
                print(f"  目标 {i+1}: 类别={cls}, 置信度={conf:.2f}")

if __name__ == "__main__":
    # 使用示例
    model_path = r"C:\Users\<用户名>\.anylabeling\runs\segment\exp\weights\best.pt"
    test_image = "./test_images"  # 测试图像目录或单张图像路径
    
    test_model(
        model_path=model_path,
        image_path=test_image,
        conf_threshold=0.25,
        save_dir="./test_results"
    )

脚本说明

  • 加载模型:使用 YOLO() 加载训练好的模型
  • 批量处理:支持单张图像或整个目录
  • 结果保存:自动保存标注后的图像
  • 信息输出:打印检测到的目标数量和详细信息

10.3 推理脚本(用于实际应用)

创建 inference.py

from ultralytics import YOLO
import cv2
import numpy as np
from pathlib import Path

class YOLOSegmentInference:
    """YOLO 分割模型推理类"""
    
    def __init__(self, model_path, conf_threshold=0.25, device='cuda'):
        """
        初始化推理器
        
        Args:
            model_path: 模型路径(.pt 或 .onnx)
            conf_threshold: 置信度阈值
            device: 推理设备('cuda' 或 'cpu')
        """
        self.model = YOLO(model_path)
        self.conf_threshold = conf_threshold
        self.device = device
    
    def predict_image(self, image_path, save_path=None, show=False):
        """
        对单张图像进行推理
        
        Args:
            image_path: 图像路径
            save_path: 保存路径(可选)
            show: 是否显示结果
        
        Returns:
            results: 检测结果
        """
        # 推理
        results = self.model.predict(
            source=image_path,
            conf=self.conf_threshold,
            device=self.device,
            verbose=False
        )
        
        # 绘制结果
        annotated_frame = results[0].plot()
        
        # 保存结果
        if save_path:
            cv2.imwrite(save_path, annotated_frame)
            print(f"结果已保存到: {save_path}")
        
        # 显示结果
        if show:
            cv2.imshow("Detection Result", annotated_frame)
            cv2.waitKey(0)
            cv2.destroyAllWindows()
        
        return results
    
    def predict_video(self, video_path, output_path=None, show=False):
        """
        对视频进行推理
        
        Args:
            video_path: 视频路径
            output_path: 输出视频路径(可选)
            show: 是否显示结果
        
        Returns:
            results: 检测结果
        """
        # 推理
        results = self.model.predict(
            source=video_path,
            conf=self.conf_threshold,
            device=self.device,
            save=output_path is not None,
            project=Path(output_path).parent if output_path else None,
            name=Path(output_path).stem if output_path else "predict",
            verbose=False
        )
        
        if output_path:
            print(f"结果视频已保存到: {output_path}")
        
        return results
    
    def predict_webcam(self, camera_id=0, show=True):
        """
        实时摄像头推理
        
        Args:
            camera_id: 摄像头ID(默认0)
            show: 是否显示结果
        """
        cap = cv2.VideoCapture(camera_id)
        
        while True:
            ret, frame = cap.read()
            if not ret:
                break
            
            # 推理
            results = self.model.predict(
                source=frame,
                conf=self.conf_threshold,
                device=self.device,
                verbose=False
            )
            
            # 绘制结果
            annotated_frame = results[0].plot()
            
            # 显示
            if show:
                cv2.imshow("Real-time Detection", annotated_frame)
                if cv2.waitKey(1) & 0xFF == ord('q'):
                    break
        
        cap.release()
        cv2.destroyAllWindows()
    
    def get_detection_info(self, results):
        """
        提取检测信息
        
        Args:
            results: 模型推理结果
        
        Returns:
            detections: 检测信息列表
        """
        detections = []
        
        for result in results:
            boxes = result.boxes
            masks = result.masks
            
            for i in range(len(boxes)):
                # 获取边界框信息
                box = boxes[i]
                cls = int(box.cls[0])
                conf = float(box.conf[0])
                xyxy = box.xyxy[0].cpu().numpy()  # [x1, y1, x2, y2]
                
                # 获取分割掩码(如果有)
                mask = None
                if masks is not None and i < len(masks.data):
                    mask = masks.data[i].cpu().numpy()
                
                detections.append({
                    'class_id': cls,
                    'confidence': conf,
                    'bbox': xyxy.tolist(),
                    'mask': mask.tolist() if mask is not None else None
                })
        
        return detections

if __name__ == "__main__":
    # 使用示例
    
    # 初始化推理器
    model_path = r"C:\Users\<用户名>\.anylabeling\runs\segment\exp\weights\best.pt"
    inferencer = YOLOSegmentInference(
        model_path=model_path,
        conf_threshold=0.25,
        device='cuda'  # 或 'cpu'
    )
    
    # 1. 图像推理
    print("=== 图像推理 ===")
    results = inferencer.predict_image(
        image_path="./test_image.jpg",
        save_path="./result_image.jpg",
        show=True
    )
    
    # 获取检测信息
    detections = inferencer.get_detection_info(results)
    print(f"检测到 {len(detections)} 个目标")
    for i, det in enumerate(detections):
        print(f"  目标 {i+1}: 类别={det['class_id']}, 置信度={det['confidence']:.2f}")
    
    # 2. 视频推理
    # print("=== 视频推理 ===")
    # inferencer.predict_video(
    #     video_path="./test_video.mp4",
    #     output_path="./result_video.mp4",
    #     show=True
    # )
    #
    # 3. 批量推理
    # print("=== 批量推理 ===")
    # inferencer.predict_batch(
    #     image_dir="./test_images/",
    #     output_dir="./results/",
    #     save_txt=True  # 保存检测结果到txt文件
    # )

10.4 推理脚本详细说明

10.4.1 类初始化参数
  • model_path:模型权重文件路径(.pt 或 .onnx)
  • conf_threshold:置信度阈值(0-1),低于此值的检测会被过滤
  • device:推理设备,'cuda'(GPU)或 'cpu'
  • iou_threshold:NMS的IoU阈值,用于去除重叠的检测框
10.4.2 主要方法
  1. predict_image():单张图像推理

    • image_path:输入图像路径
    • save_path:保存结果图像路径(可选)
    • show:是否显示结果(默认False)
  2. predict_video():视频推理

    • video_path:输入视频路径
    • output_path:输出视频路径
    • show:是否实时显示(默认False)
  3. predict_batch():批量图像推理

    • image_dir:图像目录
    • output_dir:结果保存目录
    • save_txt:是否保存检测结果到txt文件
  4. get_detection_info():获取检测信息

    • 返回检测结果列表,每个结果包含:
      • class_id:类别ID
      • confidence:置信度
      • bbox:边界框坐标 [x1, y1, x2, y2]
      • mask:分割掩码(如果可用)

10.5 使用 ONNX 模型推理

如果导出了 ONNX 格式模型,可以使用 ONNX Runtime 进行推理:

import onnxruntime as ort
import cv2
import numpy as np

class ONNXInference:
    def __init__(self, onnx_path, conf_threshold=0.25):
        """
        使用 ONNX 模型进行推理
        
        Args:
            onnx_path: ONNX 模型路径
            conf_threshold: 置信度阈值
        """
        self.conf_threshold = conf_threshold
        self.session = ort.InferenceSession(onnx_path)
        self.input_name = self.session.get_inputs()[0].name
        
    def preprocess(self, image):
        """图像预处理"""
        # 调整大小到模型输入尺寸(通常是640x640)
        img = cv2.resize(image, (640, 640))
        # 转换为RGB
        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        # 归一化到0-1
        img = img.astype(np.float32) / 255.0
        # 转换为CHW格式
        img = np.transpose(img, (2, 0, 1))
        # 添加batch维度
        img = np.expand_dims(img, axis=0)
        return img
    
    def postprocess(self, outputs, original_shape):
        """后处理:解析模型输出"""
        # outputs 是模型输出的原始结果
        # 需要根据具体的模型输出格式进行解析
        # 这里是一个简化的示例
        detections = []
        # ... 解析逻辑 ...
        return detections
    
    def predict(self, image_path):
        """预测单张图像"""
        image = cv2.imread(image_path)
        original_shape = image.shape
        
        # 预处理
        input_data = self.preprocess(image)
        
        # 推理
        outputs = self.session.run(None, {self.input_name: input_data})
        
        # 后处理
        detections = self.postprocess(outputs, original_shape)
        
        return detections

# 使用示例
if __name__ == "__main__":
    onnx_path = r"C:\Users\<用户名>\.anylabeling\runs\segment\exp\weights\best.onnx"
    inferencer = ONNXInference(onnx_path)
    
    results = inferencer.predict("./test_image.jpg")
    print(f"检测到 {len(results)} 个目标")

10.6 性能优化建议

  1. 使用GPU加速

    • 确保安装了CUDA版本的PyTorch
    • 设置 device='cuda'
  2. 批量推理

    • 对于多张图像,使用批量推理比单张推理更高效
    • 可以设置合适的batch size
  3. 模型量化

    • 使用INT8量化可以显著提升推理速度
    • 精度损失通常很小
  4. TensorRT优化(NVIDIA GPU):

    • 将ONNX模型转换为TensorRT格式
    • 可以获得更快的推理速度

10.7 实践中使用的脚本文件的内容

# check.py
from ultralytics import YOLO
import glob

# 加载训练好的最佳模型
model = YOLO('/home/ubuntu/xanylabeling_data/trainer/ultralytics/runs/segment/exp/weights/best.pt')

# 在测试集上验证
results = model.val(
    data='/home/ubuntu/dataset/data.yaml',
    split='val'  # 使用验证集
)

print(f"mAP50: {results.box.map50:.3f}")  # 检测精度
print(f"mAP50-95: {results.box.map:.3f}")  # 综合精度

# infer.py
from ultralytics import YOLO
import glob
import torch

# 设置PyTorch默认使用GPU
# torch.cuda.set_device(0)  # 使用第一个GPU

# 加载训练好的最佳模型
model = YOLO('/home/ubuntu/xanylabeling_data/trainer/ultralytics/runs/segment/exp/weights/best.pt')

# 单张图片预测
results = model('/home/ubuntu/dataset/images/train/微信图片_20251128132525_22.jpg')
# results[0].show()  # 显示结果
results[0].save('result.jpg')  # 保存结果

# 只输出检测到的物体名称
detected_objects = []

for result in results:
    for box in result.boxes:
        class_id = int(box.cls[0])
        class_name = result.names[class_id]
        detected_objects.append(class_name)

if detected_objects:
    print("📋 检测到的物体:")
    for obj in set(detected_objects):  # 使用set去重
        count = detected_objects.count(obj)
        print(f"   {obj}: {count}个")
else:
    print("❌ 没有检测到任何物体")

# # 批量预测
# results = model(['图片1.jpg', '图片2.jpg', '图片3.jpg'])
# for i, r in enumerate(results):
#     r.save(f'result_{i}.jpg')

11. 常见问题与解决方案

11.1 训练相关问题

问题1:训练时内存不足

  • 解决方案
    • 减小batch size
    • 减小图像尺寸
    • 使用更小的模型(如yolov8n)

问题2:训练loss不下降

  • 解决方案
    • 检查数据集标注是否正确
    • 调整学习率
    • 增加训练轮数
    • 检查数据增强是否过度

问题3:验证集精度很低

  • 解决方案
    • 检查训练集和验证集的数据分布是否一致
    • 增加训练数据量
    • 调整数据增强策略

11.2 推理相关问题

问题1:推理速度慢

  • 解决方案
    • 使用GPU加速
    • 使用更小的模型
    • 减小输入图像尺寸
    • 使用ONNX或TensorRT优化

问题2:检测结果不准确

  • 解决方案
    • 调整置信度阈值
    • 检查模型是否在相似场景上训练
    • 考虑重新训练或微调模型

问题3:内存占用过高

  • 解决方案
    • 减小batch size
    • 使用CPU推理(虽然慢但内存占用小)
    • 处理完一张图像后释放内存

11.3 数据相关问题

问题1:标注格式错误

  • 解决方案
    • 检查YOLO格式是否正确
    • 确保坐标已归一化(0-1之间)
    • 检查类别ID是否从0开始

问题2:图像和标签不匹配

  • 解决方案
    • 确保图像和标签文件名一致(扩展名不同)
    • 检查文件是否在正确的目录中
    • 使用脚本验证文件对应关系

12. 进阶技巧

12.1 数据增强策略

data.yaml 中可以配置数据增强:

# 数据增强配置
augment:
  hsv_h: 0.015  # 色调增强
  hsv_s: 0.7    # 饱和度增强
  hsv_v: 0.4    # 明度增强
  degrees: 10   # 旋转角度
  translate: 0.1  # 平移
  scale: 0.5    # 缩放
  flipud: 0.0   # 上下翻转概率
  fliplr: 0.5   # 左右翻转概率
  mosaic: 1.0   # Mosaic增强概率
  mixup: 0.0    # Mixup增强概率

12.2 模型集成

训练多个模型并集成结果可以提高精度:

from ultralytics import YOLO
import numpy as np

# 加载多个模型
models = [
    YOLO('best_model1.pt'),
    YOLO('best_model2.pt'),
    YOLO('best_model3.pt'),
]

def ensemble_predict(image_path, models, conf_threshold=0.25):
    """模型集成预测"""
    all_results = []
    
    for model in models:
        results = model(image_path, conf=conf_threshold)
        all_results.append(results[0])
    
    # 集成策略:投票或平均
    # 这里简化处理,实际需要更复杂的集成逻辑
    return all_results[0]  # 返回第一个模型的结果作为示例

12.3 模型剪枝与量化

from ultralytics import YOLO

# 加载模型
model = YOLO('best.pt')

# 导出为INT8量化模型
model.export(format='onnx', imgsz=640, int8=True)

# 导出为TensorRT格式(需要NVIDIA GPU)
model.export(format='engine', imgsz=640)

13. 参考资料


教程完成! 参考这份文档可以:

  1. 安装和使用 X-AnyLabeling 进行图像标注
  2. 使用 AI 辅助标注提高效率
  3. 导出 YOLO 格式的标注数据
  4. 准备标准的数据集结构
  5. 训练 YOLO 分割模型
  6. 导出和转换模型格式
  7. 使用训练好的模型进行推理

14. 难点总结

  1. 将标注图片时候的标签和 data.yaml 中的内容对齐比较麻烦,容易出错。
  2. 将 dataset 的目录结构与 data.yaml 中的内容对齐比较麻烦,容易出错。
  3. 知道怎么下载训练时使用的 pt 模型很重要,容易和 AI 标注时使用的模型混淆。
  4. 总的来说,需要熟练的掌握数据集的构造结构,标签的格式,yaml 文件怎么写,初始权重文件怎么下载;然后才是怎么标注。
### X-AnyLabeling 工具进行 YOLO11 模型 OBB 自动标注的实现方法 X-AnyLabeling 是一个强大的工具,支持多种标注格式自动标注功能[^2]。为了使用 X-AnyLabeling 实现 YOLO11 模型的 OBB( Oriented Bounding Box )自动标注,可以按照以下方法操作: #### 1. 安装 X-AnyLabeling 首先需要安装 X-AnyLabeling 工具。可以通过以下两种方式进行安装: - **方法一**:从官方 GitHub 下载源码并安装。 - **方法二**:寻找网盘资源下载预编译版本[^2]。 安装完成后,确保工具能够正常运行。 #### 2. 配置 YOLO11 模型 在 X-AnyLabeling 中集成 YOLO11 模型需要完成以下步骤: - **定义配置文件**:在 `X-AnyLabeling/anylabeling/configs/auto_labeling` 目录下创建一个新的配置文件,用于指定模型参数、输入输出格式等信息[^1]。 - **添加模型配置**:编辑 `X-AnyLabeling/anylabeling/configs/auto_labeling/models.yaml` 文件,将 YOLO11 模型的相关配置添加到其中[^1]。 #### 3. 实现模型推理逻辑 在 `X-AnyLabeling/anylabeling/services/auto_labeling` 目录下实现 YOLO11 模型的推理逻辑。具体来说,需要编写代码以加载模型并处理输入图像,生成 OBB 标注结果。以下是一个简单的代码示例: ```python import torch from anylabeling.services.auto_labeling.model_manager import BaseModel class YOLO11_OBB(BaseModel): def __init__(self, config_file, model_file, label_file=None, device="cpu"): super().__init__(config_file, model_file, label_file, device) self.model = torch.hub.load('ultralytics/yolov5', 'custom', path=model_file, force_reload=True) def predict(self, image): results = self.model(image) obb_annotations = [] for detection in results.xywh: x, y, w, h, angle = detection[:5] obb_annotations.append({ "x": x, "y": y, "width": w, "height": h, "angle": angle }) return obb_annotations ``` 此代码实现了 YOLO11 模型的加载与推理,并返回 OBB 格式的标注结果。 #### 4. 添加模型到管理器 最后,在 `X-AnyLabeling/anylabeling/services/auto_labeling/model_manager.py` 文件中,将 YOLO11 模型添加到模型管理器中,以便用户可以在界面中选择该模型进行自动标注。 --- #### 输出格式支持 X-AnyLabeling 支持多种标注格式输出,包括但不限于 YOLOYOLO-OBB、COCO DOTA 格式。确保在配置文件中正确指定输出格式,以满足后续训练或分析的需求。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值