首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

YOLO11 目标检测 | 自动标注 | 预标注 | 标签格式转换 | 手动校正标签

  • 25-02-18 14:02
  • 2393
  • 13683
blog.csdn.net

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

目录

1、预训练权重

 2、生成预标注

3、分析YOLO11的目标检测格式

4、分析Labelme标注工具的格式

5、生成json标注文件

6、手动校正标签

7、Labelme的json转为YOLO的txt

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


1、预训练权重

首先我们去官网下载,YOLO11目标检测的预训练权重,如下表格式所示:

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

Modelsize
(pixels)
mAPval
50-95
Speed
CPU ONNX
(ms)
Speed
T4 TensorRT10
(ms)
params
(M)
FLOPs
(B)
YOLO11n64039.556.1 ± 0.81.5 ± 0.02.66.5
YOLO11s64047.090.0 ± 1.22.5 ± 0.09.421.5
YOLO11m64051.5183.2 ± 2.04.7 ± 0.120.168.0
YOLO11l64053.4238.6 ± 1.46.2 ± 0.125.386.9
YOLO11x64054.7462.8 ± 6.711.3 ± 0.256.9194.9

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

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

 2、生成预标注

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

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

  1. from ultralytics import YOLO
  2. # 加载训练的模型
  3. model = YOLO(r"runs/detect/train/weights/best.pt")
  4. # 对指定的图像文件夹进行推理,并设置各种参数
  5. results = model.predict(
  6. source="datasets/det_20241020/images/", # 新的图片,待标注的图片
  7. conf=0.45, # 置信度阈值
  8. iou=0.6, # IoU 阈值
  9. imgsz=640, # 图像大小
  10. half=False, # 使用半精度推理
  11. device=None, # 使用设备,None 表示自动选择,比如'cpu','0'
  12. max_det=300, # 最大检测数量
  13. vid_stride=1, # 视频帧跳跃设置
  14. stream_buffer=False, # 视频流缓冲
  15. visualize=False, # 可视化模型特征
  16. augment=False, # 启用推理时增强
  17. agnostic_nms=False, # 启用类无关的NMS
  18. classes=None, # 指定要检测的类别
  19. retina_masks=False, # 使用高分辨率分割掩码
  20. embed=None, # 提取特征向量层
  21. show=False, # 是否显示推理图像
  22. save=True, # 保存推理结果
  23. save_frames=False, # 保存视频的帧作为图像
  24. save_txt=True, # 保存检测结果到文本文件
  25. save_conf=False, # 保存置信度到文本文件
  26. save_crop=False, # 保存裁剪的检测对象图像
  27. show_labels=True, # 显示检测的标签
  28. show_conf=True, # 显示检测置信度
  29. show_boxes=True, # 显示检测框
  30. line_width=None # 设置边界框的线条宽度,比如2,4
  31. )
  • 需要修改model = YOLO(r"runs/detect/train/weights/best.pt")中的权重路径,替换为自己训练的
  • 同时需要修改source="datasets/det_20241020/images/", 这里是指新的图片,即待标注的图片
  • 其他推理参数,根据任务情况,自行修改了;比如:置信度conf、iou、图像大小imgsz等等。

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

- runs/detect/predict/

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

        - picture1.jpg

        - picture2.jpg

                .....

        - pictureN.jpg

3、分析YOLO11的目标检测格式

YOLO11的标签文件是一个包含每行一个标签的txt文件。

每一行的格式是: 。其中:

  • 是类别索引。
  • 和是目标的中心点坐标(归一化到0-1)。
  • 和是目标的宽度和高度(归一化到0-1)。

txt标签示例数据,表示有两个物体:

0 0.5192 0.4512 0.3985 0.7572
3 0.5061 0.5921 0.2631 0.4561

  • 第一行表示物体1,类别为0,0.5192是中心点x坐标,0.4512是中心点y坐标,0.3985是宽度, 0.7572是高度。
  • 第二行表示物体2,类别为3,0.5061是中心点x坐标,0.5921是中心点y坐标,0.2631是宽度, 0.4561是高度。

4、分析Labelme标注工具的格式

在目标检测中,我们使用Labelme工具进行标注,选择“创建矩形”,对物体进行标注。

  • 标注后点击保存,会生成JSON标注文件;
  • 这样能使用Labelme,可视化检查预标注的结果,方便人工手动修正标签

LabelMe使用的是JSON格式,每个标签是一个形状(shape)对象,包含以下信息: 

  • label: 标签的名称。
  • points: 多边形的点列表(包含多边形顶点的坐标)。
  • group_id: (可选)用于将不同形状分组的ID。
  • shape_type: 形状类型(例如rectangle, circle等)。
  • flags: (可选)一些额外的标记信息。

5、生成json标注文件

编写程序,遍历该文件夹中的所有txt文件,然后将生成的Labelme的JSON文件保存到指定的输出文件夹中

  • 定义类别映射:创建一个字典,将YOLO11类别ID映射到相应的类名。

  • 转换函数:定义yolo_to_labelme函数,接收YOLO11格式的txt文件路径和图像尺寸,读取标注数据,计算绝对坐标,并格式化为LabelMe的JSON结构。

  • 主函数实现:

    • 指定输入图像和标签文件夹路径,以及输出JSON文件的路径。
    • 检查输出目录是否存在,如不存在则创建。
    • 遍历标签文件夹中的所有.txt文件,读取相应的图像文件。
    • 使用OpenCV读取图像以获取其高度和宽度。
    • 调用转换函数生成标注数据。
    • 将生成的LabelMe格式数据写入新的JSON文件。

这里会提供源代码,需要根据我们的数据修改以下部分:

  1. import os
  2. import json
  3. import cv2
  4. # 自定义类别映射
  5. class_map = {
  6. 0: 'class_name1', # 类别 0 对应的名称
  7. 1: 'class_name2', # 类别 1 对应的名称
  8. 2: 'class_name3' # 类别 2 对应的名称
  9. }
  10. # YOLO11的txt标签,转为Labelme的json文件
  11. def yolo_to_labelme(txt_path, img_width, img_height):
  12. with open(txt_path, 'r') as file:
  13. lines = file.readlines()
  14. shapes = []
  15. for line in lines:
  16. parts = line.strip().split()
  17. class_id = int(parts[0])
  18. x_center = float(parts[1])
  19. y_center = float(parts[2])
  20. width = float(parts[3])
  21. height = float(parts[4])
  22. # 转换为绝对坐标
  23. x_center *= img_width
  24. y_center *= img_height
  25. width *= img_width
  26. height *= img_height
  27. # 计算矩形的四个顶点
  28. x1 = x_center - width / 2
  29. y1 = y_center - height / 2
  30. x2 = x_center + width / 2
  31. y2 = y_center + height / 2
  32. shapes.append({
  33. 'label': class_map[class_id],
  34. 'points': [[x1, y1], [x2, y2]],
  35. 'group_id': None,
  36. 'shape_type': 'rectangle',
  37. 'flags': {}
  38. })
  39. return shapes
  40. def main():
  41. # 文件夹路径
  42. image_folder_path = r"./datasets/seg-datasetsv2/images" # 这里指定图片的文件夹路径
  43. txt_folder_path = r"./datasets/seg-datasetsv2/labels" # 这里指定YOLO的txt_labels的文件夹路径
  44. json_output_path = r"./datasets/seg-datasetsv2/json_labels" # 这里指定待会生成Labelme的json_labels的文件夹路径
  45. # 检查输出文件夹是否存在,不存在则创建
  46. if not os.path.exists(json_output_path):
  47. os.makedirs(json_output_path)
  48. # 遍历所有txt文件并转换
  49. for txt_file in os.listdir(txt_folder_path):
  50. if txt_file.endswith('.txt'):
  51. txt_path = os.path.join(txt_folder_path, txt_file)
  52. # 获取与txt文件同名的图片路径
  53. img_file = txt_file.replace('.txt', '.jpg') # 假设图片是jpg格式
  54. img_path = os.path.join(image_folder_path, img_file)
  55. try:
  56. # 使用OpenCV读取图片分辨率
  57. img = cv2.imread(img_path)
  58. if img is None:
  59. raise FileNotFoundError(f"Image file not found: {img_path}")
  60. img_height, img_width, _ = img.shape
  61. shapes = yolo_to_labelme(txt_path, img_width, img_height)
  62. # 创建LabelMe格式的json文件
  63. labelme_data = {
  64. 'version': '4.5.6',
  65. 'flags': {},
  66. 'shapes': shapes,
  67. 'imagePath': img_file,
  68. 'imageData': None,
  69. 'imageHeight': img_height,
  70. 'imageWidth': img_width
  71. }
  72. json_path = os.path.join(json_output_path, txt_file.replace('.txt', '.json'))
  73. with open(json_path, 'w') as json_file:
  74. json.dump(labelme_data, json_file, indent=2)
  75. except Exception as e:
  76. print(f"Error processing {img_file}: {e}")
  77. # 主函数入口
  78. if __name__ == "__main__":
  79. main()

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

  1. # 定义类别标签映射
  2. class_map = {
  3. 0: 'person', # 类别 0 对应的名称是person
  4. 1: 'bicycle', # 类别 1 对应的名称是bicycle
  5. 2: 'car' # 类别 2 对应的名称是car
  6. }

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

  1. image_folder_path = r"./datasets/seg-datasetsv2/images" # 这里指定图片的文件夹路径
  2. txt_folder_path = r"./datasets/seg-datasetsv2/labels" # 这里指定YOLO的txt_labels的文件夹路径
  3. json_output_path = r"./datasets/seg-datasetsv2/json_labels" # 这里指定待会生成Labelme的json_labels的文件夹路径

运行代码,会生成用于YOLO11目标检测的JSON标签文件。

6、手动校正标签

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

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

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

7、Labelme的json转为YOLO的txt

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

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

通过下面代码,把Labelme的json转为YOLO的txt

 方案1——单个文件转换

该代码用于将LabelMe格式的JSON标注文件,转换为YOLO11格式的标注文件,函数解析:

convert_labelme_to_yolo(json_path, output_dir):

  • 功能: 将单个LabelMe格式的JSON文件转换为YOLO11格式。
  • 参数:
    • json_path (str): 输入的LabelMe格式JSON文件路径。
    • output_dir (str): 输出的YOLO11格式标注文件夹路径。
  • 操作:
    • 读取JSON文件,获取图像宽度和高度。
    • 遍历所有标注形状,提取标签和坐标,计算YOLO11所需的中心点和宽高。
    • 将结果写入以相同文件名命名的TXT文件中。

示例代码如下所示:

  1. import json
  2. import os
  3. # 定义标签映射,将类别名称映射为ID
  4. label_map = {
  5. "car": 0, # 汽车
  6. "bus": 1 # 公交车
  7. }
  8. def convert_labelme_to_yolo(json_path, output_dir):
  9. """
  10. 将LabelMe格式的JSON文件转换为YOLO11格式的标注文件。
  11. 参数:
  12. json_path (str): 输入的LabelMe格式JSON文件路径。
  13. output_dir (str): 输出的YOLO11格式标注文件夹路径。
  14. """
  15. # 打开LabelMe格式的JSON文件
  16. with open(json_path, 'r') as f:
  17. labelme_data = json.load(f) # 读取JSON数据
  18. # 获取图像的宽度和高度
  19. image_width = labelme_data['imageWidth']
  20. image_height = labelme_data['imageHeight']
  21. yolo_annotations = [] # 存储YOLO11格式的标注
  22. # 遍历所有的标注形状
  23. for shape in labelme_data['shapes']:
  24. label = shape['label'] # 获取标签名称
  25. if label not in label_map:
  26. continue # 如果标签未定义,则忽略
  27. class_id = label_map[label] # 获取对应的类别ID
  28. points = shape['points'] # 获取标注的坐标点
  29. if shape['shape_type'] == 'rectangle': # 如果是矩形
  30. (x1, y1), (x2, y2) = points # 获取矩形的两个顶点
  31. elif shape['shape_type'] == 'polygon': # 如果是多边形
  32. x1, y1 = min(point[0] for point in points), min(point[1] for point in points) # 计算多边形的左上角
  33. x2, y2 = max(point[0] for point in points), max(point[1] for point in points) # 计算多边形的右下角
  34. else:
  35. continue # 其他类型不处理
  36. # 计算YOLO11格式所需的中心点和宽高
  37. x_center = (x1 + x2) / 2.0 / image_width # 计算中心点x坐标
  38. y_center = (y1 + y2) / 2.0 / image_height # 计算中心点y坐标
  39. width = (x2 - x1) / image_width # 计算宽度
  40. height = (y2 - y1) / image_height # 计算高度
  41. # 添加YOLO11格式的标注到列表中
  42. yolo_annotations.append(f"{class_id} {x_center} {y_center} {width} {height}")
  43. # 构建输出文件的路径
  44. output_file = os.path.join(output_dir, os.path.splitext(os.path.basename(json_path))[0] + '.txt')
  45. # 将YOLO11格式的标注写入输出文件
  46. with open(output_file, 'w') as f:
  47. f.write('\n'.join(yolo_annotations))
  48. # 示例使用
  49. convert_labelme_to_yolo('/path/to/labelme_file.json', '/path/to/output_dir')

方案2——多个标签文件转换

读取一个文件夹下所有json文件,然后转为YOLO11的txt标签格

process_folder(input_folder, output_folder):

  • 功能: 处理输入文件夹中的所有JSON文件,转换为YOLO11格式。
  • 参数:
    • input_folder (str): 包含LabelMe格式JSON文件的输入文件夹路径。
    • output_folder (str): 用于保存YOLO11格式标注文件的输出文件夹路径。
  • 操作:
    • 创建输出文件夹(如果不存在)。
    • 遍历输入文件夹,调用转换函数处理每个以.json结尾的文件。

 示例代码如下所示:

  1. import json
  2. import os
  3. # 定义标签映射,将类别名称映射为ID
  4. label_map = {
  5. "car": 0, # 汽车
  6. "bus": 1 # 公交车
  7. }
  8. def convert_labelme_to_yolo(json_path, output_dir):
  9. """
  10. 将LabelMe格式的JSON文件转换为YOLO11格式的标注文件。
  11. 参数:
  12. json_path (str): 输入的LabelMe格式JSON文件路径。
  13. output_dir (str): 输出的YOLO11格式标注文件夹路径。
  14. """
  15. # 打开LabelMe格式的JSON文件
  16. with open(json_path, 'r') as f:
  17. labelme_data = json.load(f) # 读取JSON数据
  18. # 获取图像的宽度和高度
  19. image_width = labelme_data['imageWidth']
  20. image_height = labelme_data['imageHeight']
  21. yolo_annotations = [] # 存储YOLO11格式的标注
  22. # 遍历所有的标注形状
  23. for shape in labelme_data['shapes']:
  24. label = shape['label'] # 获取标签名称
  25. if label not in label_map:
  26. continue # 如果标签未定义,则忽略
  27. class_id = label_map[label] # 获取对应的类别ID
  28. points = shape['points'] # 获取标注的坐标点
  29. if shape['shape_type'] == 'rectangle': # 如果是矩形
  30. (x1, y1), (x2, y2) = points # 获取矩形的两个顶点
  31. elif shape['shape_type'] == 'polygon': # 如果是多边形
  32. x1, y1 = min(point[0] for point in points), min(point[1] for point in points) # 计算多边形的左上角
  33. x2, y2 = max(point[0] for point in points), max(point[1] for point in points) # 计算多边形的右下角
  34. else:
  35. continue # 其他类型不处理
  36. # 计算YOLO11格式所需的中心点和宽高
  37. x_center = (x1 + x2) / 2.0 / image_width # 计算中心点x坐标
  38. y_center = (y1 + y2) / 2.0 / image_height # 计算中心点y坐标
  39. width = (x2 - x1) / image_width # 计算宽度
  40. height = (y2 - y1) / image_height # 计算高度
  41. # 添加YOLO11格式的标注到列表中
  42. yolo_annotations.append(f"{class_id} {x_center} {y_center} {width} {height}")
  43. # 构建输出文件的路径
  44. output_file = os.path.join(output_dir, os.path.splitext(os.path.basename(json_path))[0] + '.txt')
  45. # 将YOLO11格式的标注写入输出文件
  46. with open(output_file, 'w') as f:
  47. f.write('\n'.join(yolo_annotations))
  48. def process_folder(input_folder, output_folder):
  49. """
  50. 处理输入文件夹中的所有JSON文件,并将其转换为YOLO11格式的标注文件。
  51. 参数:
  52. input_folder (str): 输入文件夹路径,包含LabelMe格式的JSON文件。
  53. output_folder (str): 输出文件夹路径,用于保存YOLO11格式的标注文件。
  54. """
  55. # 创建输出文件夹(如果不存在)
  56. os.makedirs(output_folder, exist_ok=True)
  57. # 处理输入文件夹中的每个 JSON 文件
  58. for filename in os.listdir(input_folder):
  59. if filename.endswith(".json"): # 只处理以 .json 结尾的文件
  60. json_path = os.path.join(input_folder, filename) # 获取完整的JSON文件路径
  61. convert_labelme_to_yolo(json_path, output_folder) # 调用转换函数
  62. # 示例使用
  63. input_folder = "/mnt/data/json_labels" # 输入json_labels文件夹路径
  64. output_folder = "/mnt/data/yolo11_txt_labels" # 输出txt_labels文件夹路径
  65. process_folder(input_folder, output_folder) # 处理文件夹中的所有JSON文件
  66. # 列出输出文件夹中的文件以确认
  67. os.listdir(output_folder) # 打印输出文件夹中的文件列表

我们使用上面代码时,需要设置输入的json_labels文件夹路径、输出txt_labels文件夹路径:

  1. input_folder = "/mnt/data/json_labels" # 输入json_labels文件夹路径
  2. output_folder = "/mnt/data/yolo11_txt_labels" # 输出txt_labels文件夹路径

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

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

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

YOLO11目标检测-训练模型参考我这篇文章:

http://iyenn.com/rec/1657167.html?spm=1001.2014.3001.5501

  YOLO11相关文章推荐:

一篇文章快速认识YOLO11 | 关键改进点 | 安装使用 | 模型训练和推理-CSDN博客

一篇文章快速认识 YOLO11 | 实例分割 | 模型训练 | 自定义数据集-CSDN博客

YOLO11模型推理 | 目标检测与跟踪 | 实例分割 | 关键点估计 | OBB旋转目标检测-CSDN博客

YOLO11模型训练 | 目标检测与跟踪 | 实例分割 | 关键点姿态估计-CSDN博客

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

YOLO11 实例分割 | 导出ONNX模型 | ONNX模型推理-CSDN博客

YOLO11 目标检测 | 导出ONNX模型 | ONNX模型推理-CSDN博客

分享完成,欢迎大家多多点赞和收藏,谢谢~

注:本文转载自blog.csdn.net的一颗小树x的文章"https://blog.csdn.net/qq_41204464/article/details/143078464"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

101
推荐
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2025 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top