labelme的安装与使用+如何将labelme标注的json格式关键点标签转为yolo格式的标签

本文详细介绍了如何使用Labelme工具进行关键点检测数据集的标注,并将其转换为YOLO所需的.json格式,包括yolo关键点检测数据集的结构说明和Labelme的安装与使用方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


标注的json格式以及转换后的yolo格式示例

如果您的json标签格式如下,进行较为轻松的修改即可使用
在这里插入图片描述
转换标签:

在这里插入图片描述

yaml文件:
需要部分修改


希望得到您的指导

非常感谢您观看我的博客,我写博客的目的是为了记录我的学习过程同时保留我的某些可重复利用代码以方便下次使用。如果您对我的内容有任何建议还请您不吝指出,非常感谢您对我的指导。

背景及代码可用范围

  1. 如果你要标注的仅是矩形框,可以有直接导出为yolo格式的标注工具。如:make senselabelimg
  2. 本博客仅针对于使用labelme标注用于yolo的json格式关键点检测数据集

一、yolo关键点检测数据集格式

yolo官网
用于训练YOLO 姿态模型的数据集标签格式如下:

每幅图像一个文本文件:数据集中的每幅图像都有一个相应的文本文件,文件名与图像文件相同,扩展名为".txt"。
每个对象一行:文本文件中的每一行对应图像中的一个对象实例。
每行对象信息:每行包含对象实例的以下信息
    对象类别索引:代表对象类别的整数(如 0 代表人,1 代表汽车等)。
    对象中心坐标:对象中心的 x 和 y 坐标,归一化为 0 和 1 之间。
    对象宽度和高度:对象的宽度和高度,标准化后介于 0 和 1 之间。
    对象关键点坐标:对象的关键点,归一化为 0 至 1。

格式为DIM = 2

<class-index> <x> <y> <width> <height> <px1> <py1> <px2> <py2> ... <pxn> <pyn>
# 采用这种格式、 <class-index> 是对象的类索引、<x> <y> <width> <height> 是边界框的坐标及宽和高,而 <px1> <py1> <px2> <py2> ... <pxn> <pyn> 是关键点的像素坐标。坐标之间用空格隔开。

格式为DIM = 3

<class-index> <x> <y> <width> <height> <px1> <py1> <p1-visibility> <px2> <py2> <p2-visibility> <pxn> <pyn> <p2-visibility>
<pn-visibility>:0代表不可见、1代表遮挡、2代表可见
# Train/val/test sets as 1) dir: path/to/imgs, 2) file: path/to/imgs.txt, or 3) list: [path/to/imgs1, path/to/imgs2, ..]
path: ../datasets/coco8-pose  # dataset root dir
train: images/train  # train images (relative to 'path') 4 images
val: images/val  # val images (relative to 'path') 4 images
test:  # test images (optional)

# Keypoints
kpt_shape: [17, 3]  # number of keypoints, number of dims (2 for x,y or 3 for x,y,visible)
#17个关键点,3维
flip_idx: [0, 2, 1, 4, 3, 6, 5, 8, 7, 10, 9, 12, 11, 14, 13, 16, 15]
#反转后关键点的对应关系

# Classes dictionary
names:
  0: person

根据官方文档,标注文件时首先要标注一个矩形框将目标框起来,然后再标注关键点数据

二、labelme的安装和使用

(一)labelme的安装

中文labelme的百度网盘
链接:https://pan.baidu.com/s/1puJdLZO-z4CPOIbiq4tFvA?pwd=1111
提取码:1111
界面如图所示

在这里插入图片描述

(二)labelme的使用

A:上一个图片
D:下一个图片
在这里插入图片描述

根据官方文档,标注文件时首先要标注一个矩形框将目标框起来,然后再标注关键点数据
在这里插入图片描述
根据官方文档,标注文件时首先要标注一个矩形框将目标框起来,然后再标注关键点数据
在这里插入图片描述标注后类似
根据官方文档,标注文件时首先要标注一个矩形框将目标框起来,然后再标注关键点数据
在这里插入图片描述

三、json2yolo

json_path:标注的json文件所在位置
yolo_path:转换后的yolo文件存放位置
image_path:标注的图片所在位置

import json
import os
from pathlib import Path
import requests
import yaml
from PIL import Image
from tqdm import tqdm   # 进度条

def count_inner_list(nested_list):
    count = 0
    for lst in nested_list:
        if isinstance(lst,list):
#             检查对象是否为指定类型
            count += 1
    return count

def output_label(json_path,yolo_path,image_path):
    # os.makedirs(yolo_path,exist_ok=True)
    json_path = Path(json_path).resolve()
    yolo_path = Path(yolo_path).resolve()
    json_parentpath = json_path.parent
    names_dict = {0: "person"}
    flipped_names = {v: k for k, v in names_dict.items()}
    for filename in tqdm(os.listdir(json_path),desc="Converting"):
        if filename.endswith('.json'):
            with open(os.path.join(json_path,filename), 'r',encoding='utf-8') as f:
                data = json.load(f)  # json files to dict:json_data
            last_part = os.path.basename(data.get("imagePath"))
            im_path = os.path.join(image_path,last_part)
            img = Image.open(requests.get(im_path,stream=True).raw if im_path.startswith("http") else im_path)
            width,height = img.size
#                 size属性获得图像宽度和高度的元组,通常形式为(width, height)
            label_filename = last_part+"txt"
            label_path = os.path.join(yolo_path,Path(label_filename).with_suffix(".txt"))
            # 转换后标签存放路径
            temp_str = ""
            previous_person_data = ""
            cnt = 0
            for label in data.get("shapes"):
                if label.get("label") == "person" :
                    cnt += 1
                    if cnt > 1:
                        current_person_data = f"{previous_person_data} {temp_str} \n"
                        previous_person_data = current_person_data
                    label_list = label.get("points")
                    x_1,y_1 = label_list[0]
                    x_2,y_2 = label_list[1]
                    x_centre = round(((x_1+x_2)/2)/width,2)
                    y_centre = round(((y_1+y_2)/2)/height,2)
                    person_width = round(abs(x_1-x_2)/width,2)
                    person_height = round(abs(y_1-y_2)/height,2)
                    temp_str = (f"{flipped_names['person']} {x_centre} {y_centre} {person_width} {person_height} ")

                else:
                    label_list = label.get("points")
                    x,y=label_list[0]
                    # 根据json文件的特征,points内部是双重列表,且内层只有一个列表,所以我们将第一个列表的值分别赋值给x,y
                    x = round(x/width,2)
                    y = round(y/height,2)

                    temp_str = (f"{temp_str} {x} {y} ")
            current_person_data = f"{previous_person_data} {temp_str}"

            with open(label_path,"a") as f:
                f.write(current_person_data + "\n")
     # Save dataset.yaml
    d = {
        "path": f"{json_parentpath}  # dataset root dir".replace('\\','/'),
        "train": f"{json_parentpath}/images/train  # train images (relative to path) 128 images".replace('\\','/'),
        "val": f"{json_parentpath}/images/val  # val images (relative to path) 128 images".replace('\\','/'),
        "test": " # test images (optional)",
        "names": names_dict,
    }  # dictionary
    file_path = os.path.join(json_parentpath, "data.yaml")
    with open(file_path,"w",encoding='utf-8')as f:
        yaml.dump(d,f,sort_keys=False)
    print("Conversion completed successfully!")

if __name__ == '__main__':
    output_label(r"E:\datasets\jsons",r"E:\datasets\labels",r"E:\datasets\images")

### Labelme 使用教程:创建 YOLO 格式的人体姿态数据集 #### 一、YOLO 关键点检测数据集格式 YOLOv5 和 YOLOv7 的关键点检测数据集通常遵循特定的文件结构和标注格式。对于每张图像,YOLO 需要一个对应的 `.txt` 文件来描述其中的关键点位置。 - **文件夹结构** - `images/`: 存储原始图片 - train/ - val/ - `labels/`: 存储对应于上述图片的标签文件 - train/ - val/ - **标签文件内容** 每一行代表一个人体实例中的所有关键点坐标及其类别 ID: ``` <class_id> <x_center> <y_center> <width> <height> <x1> <y1> ... <xN> <yN> ``` 这里 `<class_id>` 是目标类别的索引编号;`(x_center, y_center)` 表示边界框中心点相对于整幅图的比例坐标;而 `(width, height)` 则表示该矩形区域宽度高度占整个画面百分比大小[^1]。 #### 二、Labelme 安装使用 ##### (一)Labelme 安装 为了能够顺利运行 labelme 工具并完成后续操作,建议按照官方文档说明来进行环境配置: ```bash pip install labelme ``` 如果遇到依赖项冲突等问题,则可以考虑通过虚拟环境中独立安装此软件包的方式加以规避[^2]。 ##### (二)Labelme 使用方法简介 启动命令行界面后输入如下指令即可打开图形化用户界面 (GUI),从而方便快捷地标记各类物体轮廓线或兴趣区(ROI): ```bash labelme ``` 此时会弹出应用程序窗口,在菜单栏选择 "Open" 来加载待处理的照片素材,并利用左侧工具栏内的选项绘制多边形形状覆盖住感兴趣的目标对象。完成后记得保存当前进度为 JSON 文件形式以便后期进一步加工处理[^3]。 #### 三、JSON 换至 YOLO 格式 当完成了对人体部位特征点的手动标记之后,下一步就是把这些信息化为适合喂给神经网络训练使用的标准格式——即前述提到过的 YOLO 文本记录样式。为此可编写一段简单的 Python 脚本来批量读取由 labelme 输出的结果集(`*.json`),再依据既定规则重新组织成新的表述方式写入相应目录下的纯文本文件中去。 下面给出了一段用于执行这种换工作的示范代码片段: ```python import json from pathlib import Path def convert_labelme_to_yolo(json_file_path: str, output_dir: str): with open(json_file_path, 'r') as f: data = json.load(f) image_width = data['imageWidth'] image_height = data['imageHeight'] shapes = [] for shape in data["shapes"]: points = shape["points"] class_name = shape["label"] # Assuming single keypoints are stored directly under the points list. keypoint_x = sum([p[0] for p in points]) / len(points) keypoint_y = sum([p[1] for p in points]) / len(points) normalized_keypoint_x = round(keypoint_x / image_width, 6) normalized_keypoint_y = round(keypoint_y / image_height, 6) shapes.append((normalized_keypoint_x, normalized_keypoint_y)) txt_filename = Path(output_dir).joinpath(Path(json_file_path).stem + ".txt") lines = ["{} {} {}".format(class_names.index(class_name), *shape) for shape in shapes] with open(txt_filename, 'w') as file: file.write('\n'.join(lines)) if __name__ == "__main__": input_jsons_directory = "./annotations/" output_labels_directory = "./labels/" all_files = list(Path(input_jsons_directory).glob('*.json')) for file in all_files: convert_labelme_to_yolo(str(file), output_labels_directory) ``` 这段脚本实现了从 labelme 导出的 JSON 文件到 YOLO 所需 TXT 文件之间的自动化变过程。需要注意的是,具体实现细节可能会因个人需求不同有所调整,比如支持更多种类的姿态定义或是优化性能等方面的工作都可能成为未来改进的方向之一。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值