赞
踩
包含对应的python代码,测试用到的图像及其标注文件。
https://download.csdn.net/download/u011775793/88631532
可以参考: [YOLOv8] - 使用AnyLabeling对数据集进行标注(含安装和使用技巧)
可以参考:[YOLOv8] - YOLO数据集格式介绍和案例
读取AnyLabeling标注目录底下的所有json文件,遍历并逐个解释每个json文件,根据json中提供的数据(比如,被标注图像的相对路径,标注目标所在位置等),动态生成YOLO格式的图像和标注数据,分别保存到images和labels目录,最后把类别文件classes.txt也复制到目标目录。
- import base64
- import os
- import json
- import shutil
- from pathlib import Path
- from glob import glob
-
- from wepy import GLOBAL_ENCODING, get_logger, init_logger
- from wepy.helper import str_helper
-
-
- def labelme_to_yolo(label_me_json_file, cls2id_dict):
- label_me_json = json.load(open(label_me_json_file, mode='r', encoding=GLOBAL_ENCODING))
- shapes = label_me_json['shapes']
- img_width, img_height = label_me_json['imageWidth'], label_me_json['imageHeight']
- img_path = label_me_json['imagePath']
- img_data = label_me_json['imageData'] if 'imageData' in label_me_json else ''
-
- labels = []
- for s in shapes:
- s_type = s['shape_type']
- s_type = s_type.lower()
- if s_type == 'rectangle':
- pts = s['points']
- x1, y1 = pts[0] # left corner
- x2, y2 = pts[1] # right corner
- x = (x1 + x2) / 2 / img_width
- y = (y1 + y2) / 2 / img_height
- w = abs(x2 - x1) / img_width
- h = abs(y2 - y1) / img_height
- cid = cls2id_dict[s['label']]
- labels.append(f'{cid} {x} {y} {w} {h}')
-
- return labels, img_path, img_data
-
-
- class LabelMe2YoloConverter:
- def __init__(self, labelme_label_dir, labelme_classes_file, yolo_save_dir, clear_yolo_save_dir=False):
- self.labelme_label_dir = labelme_label_dir
- self.yolo_save_dir = yolo_save_dir
- self.labelme_classes_file = labelme_classes_file
- self.clear_yolo_save_dir = clear_yolo_save_dir
-
- def get_cls2id_dict(self):
- cls2id_dict = {}
- with open(self.labelme_classes_file) as f:
- for cls_id, cls_name in enumerate(f.readlines()):
- cls_name = cls_name.strip()
- if cls_name != '':
- cls2id_dict[cls_name] = cls_id
-
- return cls2id_dict
-
- def convert(self):
- yolo_dir = Path(self.yolo_save_dir)
- if self.clear_yolo_save_dir:
- shutil.rmtree(yolo_dir)
- get_logger().info(f'clear yolo save dir. yolo_dir:{yolo_dir}')
- yolo_label_dir = yolo_dir.joinpath('labels')
- yolo_image_dir = yolo_dir.joinpath('images')
- os.makedirs(yolo_label_dir, exist_ok=True)
- os.makedirs(yolo_image_dir, exist_ok=True)
- label_dir = Path(self.labelme_label_dir)
- if label_dir.exists():
- cls2id_dict = self.get_cls2id_dict()
- json_files = glob(pathname='*.json', root_dir=self.labelme_label_dir)
- total = len(json_files)
- for idx, json_file in enumerate(json_files):
- try:
- json_file = os.path.join(self.labelme_label_dir, json_file)
- get_logger().info(f'convert label. total:{total}, idx:{idx + 1}, json_file:{json_file}')
- filename = os.path.basename(json_file).rsplit('.', 1)[0]
- labels, img_path, img_data = labelme_to_yolo(json_file, cls2id_dict)
- img_prefix = str_helper.get_md5(img_path, prefix_len=8)
- if len(labels) > 0:
- src_img_path = Path(label_dir).joinpath(img_path)
- src_img_path = os.path.normpath(src_img_path) # 正规化路径,对路径中的.和..进行转换
- src_img_name = os.path.basename(src_img_path)
- target_img_path = Path(yolo_image_dir).joinpath(f'{img_prefix}_{src_img_name}')
- if os.path.exists(src_img_path):
- shutil.copy(src_img_path, target_img_path)
- get_logger().info(f'save yolo img by imagePath. yolo_img_path:{target_img_path}')
- elif img_data != '':
- with open(target_img_path, mode='wb') as f:
- f.write(base64.b64decode(img_data))
- get_logger().info(f'save yolo img by imageData. yolo_img_path:{target_img_path}')
- else:
- get_logger().error(
- f'save yolo img fail for no imagePath or imageData. json_file:{json_file}')
- continue
-
- yolo_label_path = Path(yolo_label_dir).joinpath(f'{img_prefix}_{filename}.txt')
- with open(yolo_label_path, mode='w', encoding=GLOBAL_ENCODING) as f:
- f.write('\n'.join(labels))
- get_logger().info(f'save yolo label. yolo_label_path:{yolo_label_path}')
- else:
- get_logger().error(f'there is no labels found. json_file:{json_file}')
- except Exception as e:
- get_logger().exception(f'exception happen when convert. ex:{e}, json_file:{json_file}')
-
- target_classes_file = Path(yolo_dir).joinpath('classes.txt')
- shutil.copy(self.labelme_classes_file, target_classes_file)
- get_logger().info(f'save yolo label classes. labelme_classes_file:{self.labelme_classes_file},'
- f'yolo_classes_file:{target_classes_file}')
- else:
- get_logger().error(f'The labelme label dir is not found. labelme_label_dir:{self.labelme_label_dir}')
-
-
- if __name__ == '__main__':
- init_logger('./logs/format_convert.log')
- g_labelme_classes_file = 'D:/YOLOv8Train/anylabeling_datasets/mktk_datasets/cut_640_labels/classes.txt'
- g_labelme_label_dir = 'D:/YOLOv8Train/anylabeling_datasets/mktk_datasets/cut_640_labels/'
- g_yolo_save_dir = 'D:/YOLOv8Train/v8_origin_datasets/mktk_dataset/'
- labelme_converter = LabelMe2YoloConverter(g_labelme_label_dir, g_labelme_classes_file, g_yolo_save_dir, True)
- labelme_converter.convert()
AnyLabeling的图像目录:
AnyLabeling的标注目录和类别文件:
生成的YOLO格式数据集:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。