上篇文章介绍了labelme的简单的标注操作,这篇文章在上一篇文章的基础上,介绍如何用labelme构建一个自己的数据集。
本篇文章将会以yolo格式的数据集为例。
假设我们现在有一个未标注的数据集如下图所示:
因为我们是以yolo格式为例,所以提前分割成测试集,训练集,验证集这样的格式。
然后我们要开始进行第一步,就是对自己的数据集进行标注,这里以训练集中图片为例:
这里标注完以后,要记住修改对应的保存路径:点击文件 >> 更改输出路径 >>新建一个train目录下的labels文件夹。
全部标注完就可以开始下一步:
因为这里保存的标签文件时jason格式,所以要转换成对应的txt格式文件:
感谢https://blog.csdn.net/weixin_53159002?type=blog
给的代码
# -*- coding: utf-8 -*-
import json
import os
import argparse
from tqdm import tqdm
def convert_label_json(json_dir, save_dir, classes):
"""
将标注文件从 JSON 格式转换为 YOLO 格式的文本文件,并进行坐标归一化。
:param json_dir: 包含 JSON 文件的目录路径
:param save_dir: 保存转换后文本文件的目录路径
:param classes: 类别名称列表,用逗号分隔
"""
# 获取目录中所有 JSON 文件的路径
json_paths = os.listdir(json_dir)
# 将类别字符串转换为列表
classes = classes.split(',')
# 遍历所有 JSON 文件
for json_path in tqdm(json_paths):
# 构建 JSON 文件的完整路径
path = os.path.join(json_dir, json_path)
# 打开并读取 JSON 文件
with open(path, 'r', encoding='utf-8') as load_f:
json_dict = json.load(load_f)
# 获取图像的高度和宽度
h, w = json_dict['imageHeight'], json_dict['imageWidth']
# 构建保存 TXT 文件的路径
txt_path = os.path.join(save_dir, json_path.replace('json', 'txt'))
with open(txt_path, 'w') as txt_file:
# 遍历每个形状(标注)
for shape_dict in json_dict['shapes']:
# 获取标注的类别标签
label = shape_dict['label']
# 获取类别的索引
label_index = classes.index(label)
# 获取标注的点坐标
points = shape_dict['points']
# 用于存储归一化后的坐标
points_nor_list = []
# 归一化坐标
for point in points:
points_nor_list.append(point[0] / w)
points_nor_list.append(point[1] / h)
# 将坐标转换为字符串格式
points_nor_list = list(map(lambda x: str(x), points_nor_list))
points_nor_str = ' '.join(points_nor_list)
# 构建 YOLO 格式的标签字符串
label_str = str(label_index) + ' ' + points_nor_str + '\n'
# 写入到 TXT 文件
txt_file.writelines(label_str)
if __name__ == "__main__":
"""
命令行用法示例:
python json2txt_nomalize.py --json-dir my_datasets/color_rings/jsons --save-dir
my_datasets/color_rings/txts --classes "cat,dog"
"""
# 设置命令行参数解析
parser = argparse.ArgumentParser(description='json 转换为 txt 参数')
parser.add_argument('--json-dir', type=str, default="\path\json", help='JSON 文件所在目录')
parser.add_argument('--save-dir', type=str, default="\path\labels", help='转换后 TXT 文件保存目录')
parser.add_argument('--classes', type=str, default='name1,name2...', help='类别列表,逗号分隔')
# 解析命令行参数
args = parser.parse_args()
json_dir = args.json_dir
save_dir = args.save_dir
classes = args.classes
# 调用转换函数
convert_label_json(json_dir, save_dir, classes)
记住txt文件也是保存到刚才的labels文件夹中。
最后一步,写yolo的配置文件data.yaml:
train: ../train/images
val: ../valid/images
test: ../test/images
nc: 71
names: ['airplane', 'apple', 'backpack', 'baseball bat', 'baseball glove', 'bed', 'bench', 'bicycle', 'bird', 'boat', 'book', 'bottle', 'bowl', 'broccoli', 'bus', 'cake', 'car', 'carrot', 'cell phone', 'chair', 'clock', 'couch', 'cow', 'cup', 'dining table', 'dog', 'donut', 'elephant', 'fire hydrant', 'fork', 'frisbee', 'giraffe', 'handbag', 'horse', 'hot dog', 'keyboard', 'kite', 'knife', 'laptop', 'microwave', 'motorcycle', 'mouse', 'orange', 'oven', 'parking meter', 'person', 'pizza', 'potted plant', 'refrigerator', 'remote', 'sandwich', 'scissors', 'sink', 'skateboard', 'skis', 'snowboard', 'spoon', 'sports ball', 'suitcase', 'surfboard', 'teddy bear', 'tennis racket', 'tie', 'toilet', 'traffic light', 'train', 'truck', 'tv', 'vase', 'wine glass', 'zebra']
这样一个完整的数据集就做好了: