YOLO11 实例分割 | 自动标注 | 预标注 | 标签格式转换 | 手动校正标签

机器学习算法向量数据库

picture.image

向AI转型的程序员都关注公众号 机器学习AI算法工程

本文分享使用YOLO11进行实例分割时,实现模型推理预标注、自动标注、标签格式转换、以及使用Labelme手动校正标签等功能。

目录

1、预训练权重

2、生成预标注

3、生成json标注文件

4、手动校正标签

5、Labelme的json转为YOLO的txt

6、迭代优化模型(可选)

1、预训练权重

首先我们去官网下载,YOLO11实例分割的预训练权重,如下表格式所示:

下载地址:https://github.com/ultralytics/ultralytics

picture.image

然后基于预训练权重,准备自己的数据集,进行模型训练

最终,得到效果更好的模型权重(xxx.pt或xxx.onnx)

2、生成预标注

前面得到了效果更好的模型权重,这里用它来对新的图片,进行推理,同时生成实例分割的信息。

模型推理的代码,如下所示:


          
from ultralytics import YOLO
          
 
          
# 加载预训练的YOLOv11n模型
          
model = YOLO(r"runs/segment/train3/weights/best.pt")
          
 
          
# 对指定的图像文件夹进行推理,并设置各种参数
          
results = model.predict(
          
    source="datasets/seg_20241013/images/",   # 新的图片,待标注的图片
          
    conf=0.45,                      # 置信度阈值
          
    iou=0.6,                        # IoU 阈值
          
    imgsz=640,                      # 图像大小
          
    half=False,                     # 使用半精度推理
          
    device=None,                    # 使用设备,None 表示自动选择,比如'cpu','0'
          
    max_det=300,                    # 最大检测数量
          
    vid_stride=1,                   # 视频帧跳跃设置
          
    stream_buffer=False,            # 视频流缓冲
          
    visualize=False,                # 可视化模型特征
          
    augment=False,                  # 启用推理时增强
          
    agnostic_nms=False,             # 启用类无关的NMS
          
    classes=None,                   # 指定要检测的类别
          
    retina_masks=False,             # 使用高分辨率分割掩码
          
    embed=None,                     # 提取特征向量层
          
    show=False,                     # 是否显示推理图像
          
    save=True,                      # 保存推理结果
          
    save_frames=False,              # 保存视频的帧作为图像
          
    save_txt=True,                  # 保存检测结果到文本文件
          
    save_conf=False,                # 保存置信度到文本文件
          
    save_crop=False,                # 保存裁剪的检测对象图像
          
    show_labels=True,               # 显示检测的标签
          
    show_conf=True,                 # 显示检测置信度
          
    show_boxes=True,                # 显示检测框
          
    line_width=None                 # 设置边界框的线条宽度,比如2,4
          
)
      

需要修改model = YOLO(r"runs/segment/train3/weights/best.pt")中的权重路径,替换为自己训练的

同时需要修改source="datasets/seg_20241013/images/", 这里是指新的图片,即待标注的图片

其他推理参数,根据任务情况,自行修改了;比如:置信度conf、iou、图像大小imgsz等等。

推理完成后,会保留实例分割的结果图像、标签信息文件夹(labels),它们是同一级文件夹的


          
- runs/segment/predict/
          

          
        - labels(这个文件夹是存放推理的分割信息,作为预标注的标签信息)
          

          
        - picture1.jpg
          

          
        - picture2.jpg
          

          
                .....
          

          
        - pictureN.jpg
          

      

3、生成json标注文件

在实例分割中,我们使用Labelme工具进行标注,选择“创建多边形”,对物体进行分割信息标注。

生成JSON标注文件,是因为这样能使用Labelme,可视化检查预标注的结果,方便人工手动修正标签

示例1,类别数量比较少,可以直接定义的:


          
import os
          
import json
          
import cv2
          
 
          
# 定义类别标签映射
          
LABELS = ["class1", "class2"]
          
 
          
def yolo11_to_labelme(txt_file, img_file, save_dir, labels):
          
    """
          
    将YOLO11格式的分割标签文件转换为Labelme格式的JSON文件。
          
    参数:
          
    - txt_file (str): YOLO11标签的txt文件路径。
          
    - img_file (str): 对应的图像文件路径。
          
    - save_dir (str): JSON文件保存目录。
          
    - labels (list): 类别标签列表。
          
    """
          
    # 读取图像,获取图像尺寸
          
    img = cv2.imread(img_file)
          
    height, width, _ = img.shape
          
 
          
    # 创建Labelme格式的JSON数据结构
          
    labelme_data = {
          
        "version": "4.5.9",
          
        "flags": {},
          
        "shapes": [],
          
        "imagePath": os.path.basename(img_file),
          
        "imageHeight": height,
          
        "imageWidth": width,
          
        "imageData": None  # 可以选择将图像数据转为base64后嵌入JSON
          
    }
          
 
          
    # 读取YOLO11标签文件
          
    with open(txt_file, "r") as file:
          
        for line in file.readlines():
          
            data = line.strip().split()
          
            class_id = int(data[0])  # 类别ID
          
            points = list(map(float, data[1:]))  # 获取多边形坐标
          
 
          
            # 将归一化坐标转换为实际像素坐标
          
            polygon = []
          
            for i in range(0, len(points), 2):
          
                x = points[i] * width
          
                y = points[i + 1] * height
          
                polygon.append([x, y])
          
 
          
            # 定义多边形区域
          
            shape = {
          
                "label": labels[class_id],  # 使用直接定义的类别名称
          
                "points": polygon,
          
                "group_id": None,
          
                "shape_type": "polygon",  # 分割使用多边形
          
                "flags": {}
          
            }
          
            labelme_data["shapes"].append(shape)
          
 
          
    # 保存为labelme格式的JSON文件
          
    save_path = os.path.join(save_dir, os.path.basename(txt_file).replace(".txt", ".json"))
          
    with open(save_path, "w") as json_file:
          
        json.dump(labelme_data, json_file, indent=4)
          
 
          
def convert_yolo11_to_labelme(txt_folder, img_folder, save_folder):
          
    """
          
    读取文件夹中的所有txt文件,将YOLO11标签转为Labelme的JSON格式。
          
    参数:
          
    - txt_folder (str): 存放YOLO11 txt标签文件的文件夹路径。
          
    - img_folder (str): 存放图像文件的文件夹路径。
          
    - save_folder (str): 保存转换后的JSON文件的文件夹路径。
          
    """
          
    labels = LABELS  # 直接使用定义好的标签
          
 
          
    if not os.path.exists(save_folder):
          
        os.makedirs(save_folder)
          
 
          
    for txt_file in os.listdir(txt_folder):
          
        if txt_file.endswith(".txt"):
          
            txt_path = os.path.join(txt_folder, txt_file)
          
            img_file = txt_file.replace(".txt", ".png")  # 假设图像为.png格式
          
            img_path = os.path.join(img_folder, img_file)
          
 
          
            # 检查图像文件是否存在
          
            if os.path.exists(img_path):
          
                yolo11_to_labelme(txt_path, img_path, save_folder, labels)
          
                print(f"已成功转换: {txt_file} -> JSON文件")
          
            else:
          
                print(f"图像文件不存在: {img_path}")
          
 
          
# 使用示例
          
txt_folder = r"labels_txt"  # YOLO11标签文件夹路径
          
img_folder = r"point-offer-datasetsv2"  # 图像文件夹路径
          
save_folder = r"labels_json"  # JSON文件保存路径
          
 
          
convert_yolo11_to_labelme(txt_folder, img_folder, save_folder)
      

首先修改类别映射,比如:


          
# 定义类别标签映射
          
LABELS = ["person", "bicycle", "car"]
      

然后修改一下代码中的参数:


          
txt_folder = r"./datasets/seg-datasetsv2/labels"  # YOLO11标签文件夹路径
          
img_folder = r"./datasets/seg-datasetsv2/images"  # 图像文件夹路径
          
save_folder = r"labels_json"  # JSON文件保存路径
      

运行代码,会生成用于YOLO11分割的JSON标签文件。

示例2,类别数量比较多,需要用yaml文件指定类别映射情况

示例代码如下所示:


          
import os
          
import json
          
import yaml  # 用于解析yaml文件
          
import cv2
          
 
          
def load_labels_from_yaml(yaml_file):
          
    """
          
    从YAML文件中加载类别标签。
          
    
          
    参数:
          
    - yaml_file (str): YAML文件的路径。
          
    
          
    返回值:
          
    - labels (list): 类别标签列表。
          
    """
          
    # 指定文件编码为utf-8
          
    with open(yaml_file, "r", encoding="utf-8") as file:
          
        yaml_content = yaml.safe_load(file)
          
    # 提取类别名称并转换为列表形式
          
    labels = [label for _, label in yaml_content['names'].items()]
          
    return labels
          
 
          
 
          
def yolo11_to_labelme(txt_file, img_file, save_dir, labels):
          
    """
          
    将YOLO11格式的分割标签文件转换为Labelme格式的JSON文件。
          
    参数:
          
    - txt_file (str): YOLO11标签的txt文件路径。
          
    - img_file (str): 对应的图像文件路径。
          
    - save_dir (str): JSON文件保存目录。
          
    - labels (list): 类别标签列表。
          
    """
          
    # 读取图像,获取图像尺寸
          
    img = cv2.imread(img_file)
          
    height, width, _ = img.shape
          
 
          
    # 创建Labelme格式的JSON数据结构
          
    labelme_data = {
          
        "version": "4.5.9",
          
        "flags": {},
          
        "shapes": [],
          
        "imagePath": os.path.basename(img_file),
          
        "imageHeight": height,
          
        "imageWidth": width,
          
        "imageData": None  # 可以选择将图像数据转为base64后嵌入JSON
          
    }
          
 
          
    # 读取YOLO11标签文件
          
    with open(txt_file, "r") as file:
          
        for line in file.readlines():
          
            data = line.strip().split()
          
            class_id = int(data[0])  # 类别ID
          
            points = list(map(float, data[1:]))  # 获取多边形坐标
          
 
          
            # 将归一化坐标转换为实际像素坐标
          
            polygon = []
          
            for i in range(0, len(points), 2):
          
                x = points[i] * width
          
                y = points[i + 1] * height
          
                polygon.append([x, y])
          
 
          
            # 定义多边形区域
          
            shape = {
          
                "label": labels[class_id],  # 使用从yaml加载的类别名称
          
                "points": polygon,
          
                "group_id": None,
          
                "shape_type": "polygon",  # 分割使用多边形
          
                "flags": {}
          
            }
          
            labelme_data["shapes"].append(shape)
          
 
          
    # 保存为labelme格式的JSON文件
          
    save_path = os.path.join(save_dir, os.path.basename(txt_file).replace(".txt", ".json"))
          
    with open(save_path, "w") as json_file:
          
        json.dump(labelme_data, json_file, indent=4)
          
 
          
def convert_yolo11_to_labelme(txt_folder, img_folder, save_folder, yaml_file):
          
    """
          
    读取文件夹中的所有txt文件,将YOLO11标签转为Labelme的JSON格式。
          
    参数:
          
    - txt_folder (str): 存放YOLO11 txt标签文件的文件夹路径。
          
    - img_folder (str): 存放图像文件的文件夹路径。
          
    - save_folder (str): 保存转换后的JSON文件的文件夹路径。
          
    - yaml_file (str): YAML文件的路径,用于读取类别标签。
          
    """
          
    # 从YAML文件中加载类别标签
          
    labels = load_labels_from_yaml(yaml_file)
          
 
          
    if not os.path.exists(save_folder):
          
        os.makedirs(save_folder)
          
 
          
    for txt_file in os.listdir(txt_folder):
          
        if txt_file.endswith(".txt"):
          
            txt_path = os.path.join(txt_folder, txt_file)
          
            img_file = txt_file.replace(".txt", ".jpg")  # 假设图像为.jpg格式
          
            img_path = os.path.join(img_folder, img_file)
          
 
          
            # 检查图像文件是否存在
          
            if os.path.exists(img_path):
          
                yolo11_to_labelme(txt_path, img_path, save_folder, labels)
          
                print(f"已成功转换: {txt_file} -> JSON文件")
          
            else:
          
                print(f"图像文件不存在: {img_path}")
          
 
          
# 使用示例
          
txt_folder = r"./datasets/coco8-seg/labels/val"  # YOLO11标签文件夹路径
          
img_folder = r"./datasets/coco8-seg/images/val"  # 图像文件夹路径
          
save_folder = r"./datasets/coco8-seg/labels_json/val"  # JSON文件保存路径
          
yaml_file = r"coco8-seg.yaml"  # YAML文件路径
          
 
          
convert_yolo11_to_labelme(txt_folder, img_folder, save_folder, yaml_file)
      

修改一下代码中的参数:


          
txt_folder = r"./datasets/coco8-seg/labels/val"  # YOLO11标签文件夹路径
          
img_folder = r"./datasets/coco8-seg/images/val"  # 图像文件夹路径
          
save_folder = r"./datasets/coco8-seg/labels_json/val"  # JSON文件保存路径
          
yaml_file = r"coco8-seg.yaml"  # YAML文件路径
      

示例xxx.yaml文件内容,如下所示:


          
# Ultralytics YOLO 🚀, AGPL-3.0 license
          
 
          
path: ../datasets/coco8-seg # dataset root dir
          
train: images/train # train images 
          
val: images/val # val images 
          
 
          
# Classes
          
names:
          
  0: person
          
  1: bicycle
          
  2: car
          
  3: motorcycle
          
  4: airplane
          
  5: bus
          
  6: train
          
  7: truck
          
  8: boat
          
  9: traffic light
          
  10: fire hydrant
      

4、手动校正标签

生成了JSON文件后,把图像和JSON文件放在同一个文件夹中

然后打开Labelme工具,选择“编辑多边形”,对物体进行分割信息修改

picture.image

修改完成后,点击“Save"保存修正后的标注信息

5、Labelme的json转为YOLO的txt

这里把Labelme的json转为YOLO的txt,是因为用修正后数据,作为新的数据,加入旧数据中;

重新训练之前的模型权重,这样模型会学得更好,迭代优化模型。

首先了解YOLO11的分割标签格式,如下所示:


        
            

          <class-index> <x1> <y1> <x2> <y2> ... <xn> <yn>
        
      
  • 说明:这个格式不但适用于YOLO11、YOLOv8、YOLOv5,还适用于ultralytics工程中其他版本的YOLO。

picture.image

了解YOLO11的分割标签txt文件后,通过下面代码,把Labelme的json转为YOLO的txt


          
import json
          
import os
          
 
          
'''
          
任务:实例分割,labelme的json文件, 转txt文件
          
Ultralytics YOLO format
          
<class-index> <x1> <y1> <x2> <y2> ... <xn> <yn>
          
'''
          
 
          
# 类别映射表,定义每个类别对应的ID
          
label_to_class_id = {
          
    "class_1": 0,
          
    "class_2": 1,
          
    "class_3": 2,
          
    # 根据需要添加更多类别
          
}
          
 
          
# json转txt
          
def convert_labelme_json_to_yolo(json_file, output_dir, img_width, img_height):
          
    with open(json_file, 'r') as f:
          
        labelme_data = json.load(f)
          
    
          
    # 获取文件名(不含扩展名)
          
    file_name = os.path.splitext(os.path.basename(json_file))[0]
          
    
          
    # 输出的txt文件路径
          
    txt_file_path = os.path.join(output_dir, f"{file_name}.txt")
          
 
          
    with open(txt_file_path, 'w') as txt_file:
          
        for shape in labelme_data['shapes']:
          
            label = shape['label']
          
            points = shape['points']
          
 
          
            # 根据类别映射表获取类别ID,如果类别不在映射表中,跳过该标签
          
            class_id = label_to_class_id.get(label)
          
            if class_id is None:
          
                print(f"Warning: Label '{label}' not found in class mapping. Skipping.")
          
                continue
          
 
          
            # 将点的坐标归一化到0-1范围
          
            normalized_points = [(x / img_width, y / img_height) for x, y in points]
          
 
          
            # 写入类别ID
          
            txt_file.write(f"{class_id}")
          
 
          
            # 写入多边形掩膜的所有归一化顶点坐标
          
            for point in normalized_points:
          
                txt_file.write(f" {point[0]:.6f} {point[1]:.6f}")
          
            txt_file.write("\n")
          
 
          
if __name__ == "__main__":
          
    json_dir = "json_labels"  # 替换为LabelMe标注的JSON文件目录
          
    output_dir = "labels"  # 输出的YOLO格式txt文件目录
          
    img_width = 640   # 图像宽度,根据实际图片尺寸设置
          
    img_height = 640  # 图像高度,根据实际图片尺寸设置
          
 
          
    # 创建输出文件夹
          
    if not os.path.exists(output_dir):
          
        os.makedirs(output_dir)
          
 
          
    # 批量处理所有json文件
          
    for json_file in os.listdir(json_dir):
          
        if json_file.endswith(".json"):
          
            json_path = os.path.join(json_dir, json_file)
          
            convert_labelme_json_to_yolo(json_path, output_dir, img_width, img_height)
      

首先修改类别映射,比如


          
# 类别映射表,定义每个类别对应的ID
          
label_to_class_id = {
          
    "person": 0,
          
    "bicycle": 1,
          
    "car": 2,
          
    # 根据需要添加更多类别
          
}
      

然后修改一下代码中的参数:

  • 需要修改json_dir 的路径,它用来存放 LabelMe标注的JSON文件
  • 需要修改output_dir 的路径,输出的YOLO格式txt文件目录
  • img_width 和 img_height,默认是640,分别指图片的宽度和高度,根据实际图片尺寸修改即可

运行代码,会生成用于YOLO11分割的txt标签文件。

6、迭代优化模型(可选)

然后,可以迭代优化模型。用修正后数据,作为新的数据,加入旧数据中;

重新训练之前的模型权重,这样模型会学得更好,迭代优化模型。

YOLO11实例分割-训练模型参考我这篇文章:

https://blog.csdn.net/qq\_41204464/article/details/142880722?spm=1001.2014.3001.5501

机器学习算法AI大数据技术

搜索公众号添加: datanlp

picture.image

长按图片,识别二维码

阅读过本文的人还看了以下文章:

实时语义分割ENet算法,提取书本/票据边缘

整理开源的中文大语言模型,以规模较小、可私有化部署、训练成本较低的模型为主

《大语言模型》PDF下载

动手学深度学习-(李沐)PyTorch版本

YOLOv9电动车头盔佩戴检测,详细讲解模型训练

TensorFlow 2.0深度学习案例实战

基于40万表格数据集TableBank,用MaskRCNN做表格检测

《基于深度学习的自然语言处理》中/英PDF

Deep Learning 中文版初版-周志华团队

【全套视频课】最全的目标检测算法系列讲解,通俗易懂!

《美团机器学习实践》_美团算法团队.pdf

《深度学习入门:基于Python的理论与实现》高清中文PDF+源码

《深度学习:基于Keras的Python实践》PDF和代码

特征提取与图像处理(第二版).pdf

python就业班学习视频,从入门到实战项目

2019最新《PyTorch自然语言处理》英、中文版PDF+源码

《21个项目玩转深度学习:基于TensorFlow的实践详解》完整版PDF+附书代码

《深度学习之pytorch》pdf+附书源码

PyTorch深度学习快速实战入门《pytorch-handbook》

【下载】豆瓣评分8.1,《机器学习实战:基于Scikit-Learn和TensorFlow》

《Python数据分析与挖掘实战》PDF+完整源码

汽车行业完整知识图谱项目实战视频(全23课)

李沐大神开源《动手学深度学习》,加州伯克利深度学习(2019春)教材

笔记、代码清晰易懂!李航《统计学习方法》最新资源全套!

《神经网络与深度学习》最新2018版中英PDF+源码

将机器学习模型部署为REST API

FashionAI服装属性标签图像识别Top1-5方案分享

重要开源!CNN-RNN-CTC 实现手写汉字识别

yolo3 检测出图像中的不规则汉字

同样是机器学习算法工程师,你的面试为什么过不了?

前海征信大数据算法:风险概率预测

【Keras】完整实现‘交通标志’分类、‘票据’分类两个项目,让你掌握深度学习图像分类

VGG16迁移学习,实现医学图像识别分类工程项目

特征工程(一)

特征工程(二) :文本数据的展开、过滤和分块

特征工程(三):特征缩放,从词袋到 TF-IDF

特征工程(四): 类别特征

特征工程(五): PCA 降维

特征工程(六): 非线性特征提取和模型堆叠

特征工程(七):图像特征提取和深度学习

如何利用全新的决策树集成级联结构gcForest做特征工程并打分?

Machine Learning Yearning 中文翻译稿

蚂蚁金服2018秋招-算法工程师(共四面)通过

全球AI挑战-场景分类的比赛源码(多模型融合)

斯坦福CS230官方指南:CNN、RNN及使用技巧速查(打印收藏)

python+flask搭建CNN在线识别手写中文网站

中科院Kaggle全球文本匹配竞赛华人第1名团队-深度学习与特征工程

不断更新资源

深度学习、机器学习、数据分析、python

搜索公众号添加: datayx

picture.image

0
0
0
0
评论
未登录
看完啦,登录分享一下感受吧~
暂无评论