当前位置:   article > 正文

[YOLOv8] 缺陷检测之AnyLabeling标注格式转换成YOLO格式

anylabeling标注格式转换成yolo格式

源代码说明

包含对应的python代码,测试用到的图像及其标注文件。

https://download.csdn.net/download/u011775793/88631532

如何使用AnyLabeling进行图像标注?

可以参考: [YOLOv8] - 使用AnyLabeling对数据集进行标注(含安装和使用技巧)

什么是YOLO格式数据集?

可以参考:[YOLOv8] - YOLO数据集格式介绍和案例

转换AnyLabeling的标注数据集为YOLO数据集

编程思路

读取AnyLabeling标注目录底下的所有json文件,遍历并逐个解释每个json文件,根据json中提供的数据(比如,被标注图像的相对路径,标注目标所在位置等),动态生成YOLO格式的图像和标注数据,分别保存到images和labels目录,最后把类别文件classes.txt也复制到目标目录。

源代码

  1. import base64
  2. import os
  3. import json
  4. import shutil
  5. from pathlib import Path
  6. from glob import glob
  7. from wepy import GLOBAL_ENCODING, get_logger, init_logger
  8. from wepy.helper import str_helper
  9. def labelme_to_yolo(label_me_json_file, cls2id_dict):
  10. label_me_json = json.load(open(label_me_json_file, mode='r', encoding=GLOBAL_ENCODING))
  11. shapes = label_me_json['shapes']
  12. img_width, img_height = label_me_json['imageWidth'], label_me_json['imageHeight']
  13. img_path = label_me_json['imagePath']
  14. img_data = label_me_json['imageData'] if 'imageData' in label_me_json else ''
  15. labels = []
  16. for s in shapes:
  17. s_type = s['shape_type']
  18. s_type = s_type.lower()
  19. if s_type == 'rectangle':
  20. pts = s['points']
  21. x1, y1 = pts[0] # left corner
  22. x2, y2 = pts[1] # right corner
  23. x = (x1 + x2) / 2 / img_width
  24. y = (y1 + y2) / 2 / img_height
  25. w = abs(x2 - x1) / img_width
  26. h = abs(y2 - y1) / img_height
  27. cid = cls2id_dict[s['label']]
  28. labels.append(f'{cid} {x} {y} {w} {h}')
  29. return labels, img_path, img_data
  30. class LabelMe2YoloConverter:
  31. def __init__(self, labelme_label_dir, labelme_classes_file, yolo_save_dir, clear_yolo_save_dir=False):
  32. self.labelme_label_dir = labelme_label_dir
  33. self.yolo_save_dir = yolo_save_dir
  34. self.labelme_classes_file = labelme_classes_file
  35. self.clear_yolo_save_dir = clear_yolo_save_dir
  36. def get_cls2id_dict(self):
  37. cls2id_dict = {}
  38. with open(self.labelme_classes_file) as f:
  39. for cls_id, cls_name in enumerate(f.readlines()):
  40. cls_name = cls_name.strip()
  41. if cls_name != '':
  42. cls2id_dict[cls_name] = cls_id
  43. return cls2id_dict
  44. def convert(self):
  45. yolo_dir = Path(self.yolo_save_dir)
  46. if self.clear_yolo_save_dir:
  47. shutil.rmtree(yolo_dir)
  48. get_logger().info(f'clear yolo save dir. yolo_dir:{yolo_dir}')
  49. yolo_label_dir = yolo_dir.joinpath('labels')
  50. yolo_image_dir = yolo_dir.joinpath('images')
  51. os.makedirs(yolo_label_dir, exist_ok=True)
  52. os.makedirs(yolo_image_dir, exist_ok=True)
  53. label_dir = Path(self.labelme_label_dir)
  54. if label_dir.exists():
  55. cls2id_dict = self.get_cls2id_dict()
  56. json_files = glob(pathname='*.json', root_dir=self.labelme_label_dir)
  57. total = len(json_files)
  58. for idx, json_file in enumerate(json_files):
  59. try:
  60. json_file = os.path.join(self.labelme_label_dir, json_file)
  61. get_logger().info(f'convert label. total:{total}, idx:{idx + 1}, json_file:{json_file}')
  62. filename = os.path.basename(json_file).rsplit('.', 1)[0]
  63. labels, img_path, img_data = labelme_to_yolo(json_file, cls2id_dict)
  64. img_prefix = str_helper.get_md5(img_path, prefix_len=8)
  65. if len(labels) > 0:
  66. src_img_path = Path(label_dir).joinpath(img_path)
  67. src_img_path = os.path.normpath(src_img_path) # 正规化路径,对路径中的.和..进行转换
  68. src_img_name = os.path.basename(src_img_path)
  69. target_img_path = Path(yolo_image_dir).joinpath(f'{img_prefix}_{src_img_name}')
  70. if os.path.exists(src_img_path):
  71. shutil.copy(src_img_path, target_img_path)
  72. get_logger().info(f'save yolo img by imagePath. yolo_img_path:{target_img_path}')
  73. elif img_data != '':
  74. with open(target_img_path, mode='wb') as f:
  75. f.write(base64.b64decode(img_data))
  76. get_logger().info(f'save yolo img by imageData. yolo_img_path:{target_img_path}')
  77. else:
  78. get_logger().error(
  79. f'save yolo img fail for no imagePath or imageData. json_file:{json_file}')
  80. continue
  81. yolo_label_path = Path(yolo_label_dir).joinpath(f'{img_prefix}_{filename}.txt')
  82. with open(yolo_label_path, mode='w', encoding=GLOBAL_ENCODING) as f:
  83. f.write('\n'.join(labels))
  84. get_logger().info(f'save yolo label. yolo_label_path:{yolo_label_path}')
  85. else:
  86. get_logger().error(f'there is no labels found. json_file:{json_file}')
  87. except Exception as e:
  88. get_logger().exception(f'exception happen when convert. ex:{e}, json_file:{json_file}')
  89. target_classes_file = Path(yolo_dir).joinpath('classes.txt')
  90. shutil.copy(self.labelme_classes_file, target_classes_file)
  91. get_logger().info(f'save yolo label classes. labelme_classes_file:{self.labelme_classes_file},'
  92. f'yolo_classes_file:{target_classes_file}')
  93. else:
  94. get_logger().error(f'The labelme label dir is not found. labelme_label_dir:{self.labelme_label_dir}')
  95. if __name__ == '__main__':
  96. init_logger('./logs/format_convert.log')
  97. g_labelme_classes_file = 'D:/YOLOv8Train/anylabeling_datasets/mktk_datasets/cut_640_labels/classes.txt'
  98. g_labelme_label_dir = 'D:/YOLOv8Train/anylabeling_datasets/mktk_datasets/cut_640_labels/'
  99. g_yolo_save_dir = 'D:/YOLOv8Train/v8_origin_datasets/mktk_dataset/'
  100. labelme_converter = LabelMe2YoloConverter(g_labelme_label_dir, g_labelme_classes_file, g_yolo_save_dir, True)
  101. labelme_converter.convert()

运行结果

AnyLabeling的图像目录:

AnyLabeling的标注目录和类别文件:

生成的YOLO格式数据集:

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/运维做开发/article/detail/749373
推荐阅读
相关标签
  

闽ICP备14008679号