labelme进行关键点标注并转换为yolo格式

目录

1、labelme安装和打开

在python3.9及以上环境中安装labelme,labelme要用到pyqt,所以在使用labelme之前要安装pyqt。

python 复制代码
pip install pyqt
pip install labelme

进入存放标注图像文件夹的目录,提前设置要标注的文件夹、具体标签以及存放的文件夹。其中image是图像文件夹,labels是要存放标签的文件夹,labels.txt是提前设置的标签。

python 复制代码
labelme image --output labels --labels labels.txt

打开的界面如下图所示

2、边界框和关键点标注

在标注时,要将目标框和对应的关键点分为一组,关键点也类似

标注完后记得点击上面save按钮

3、将lamelme的json格式转成yolo可以使用的txt格式

转换代码如下,可以将json格式根据group_id将目标和关键点对应起来,然后转成txt格式,每行格式为<class_id> <x_center> <y_center> <kp1_x> <kp1_y> <kp1_vis> <kp2_x> <kp2_y> <kp2_vis> ... <kpN_x> <kpN_y> <kpN_vis>

python 复制代码
import os
import json
from PIL import Image

def convert_labelme_to_yolo_keypoints(json_path, image_dir, output_dir, class_id=0, num_keypoints=7):
    os.makedirs(output_dir, exist_ok=True)

    with open(json_path, 'r') as f:
        data = json.load(f)

    image_file = data.get("imagePath", os.path.basename(json_path).replace(".json", ".jpg"))
    image_path = os.path.join(image_dir, image_file)
    image = Image.open(image_path)
    width, height = image.size

    shapes = data['shapes']
    objects = {}  # key: group_id, value: {'bbox': [...], 'keypoints': {}}

    for shape in shapes:
        g_id = shape.get("group_id")
        if g_id is None:
            continue

        label = shape['label']
        shape_type = shape['shape_type']
        pts = shape['points']

        if g_id not in objects:
            objects[g_id] = {'bbox': None, 'keypoints': {}}

        if shape_type == "rectangle" and label == "bolt":
            x1, y1 = pts[0]
            x2, y2 = pts[1]
            objects[g_id]['bbox'] = [min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2)]
        elif shape_type == "point":
            try:
                kp_id = int(label)
                objects[g_id]['keypoints'][kp_id] = pts[0]
            except ValueError:
                pass  # skip if label is not a number

    # Write YOLO-style .txt
    txt_name = os.path.basename(json_path).replace('.json', '.txt')
    out_path = os.path.join(output_dir, txt_name)

    with open(out_path, 'w') as f:
        for obj in objects.values():
            if obj['bbox'] is None:
                continue  # skip if no box

            x1, y1, x2, y2 = obj['bbox']
            x_center = (x1 + x2) / 2 / width
            y_center = (y1 + y2) / 2 / height
            box_w = (x2 - x1) / width
            box_h = (y2 - y1) / height

            keypoints = []
            for i in range(1, num_keypoints + 1):
                if i in obj['keypoints']:
                    x, y = obj['keypoints'][i]
                    keypoints += [x / width, y / height, 2]
                else:
                    keypoints += [0.0, 0.0, 0]  # 不存在该关键点

            line = f"{class_id} {x_center:.6f} {y_center:.6f} {box_w:.6f} {box_h:.6f} " + \
                   " ".join([f"{kp:.6f}" if isinstance(kp, float) else str(kp) for kp in keypoints])
            f.write(line + '\n')

    print(f"✅ 转换完成: {out_path}")


json_dir = r"path\to\labels"
image_dir = r"path\to\images"
output_dir = r"path\to\labels"

for file in os.listdir(json_dir):
    if file.endswith(".json"):
        json_path = os.path.join(json_dir, file)
        convert_labelme_to_yolo_keypoints(json_path, image_dir, output_dir)

4、将数据和标签按照9比1分为训练集和测试集

代码如下

python 复制代码
import os
import random
import shutil

# 原始文件夹路径
images_dir = 'path\to\images'
labels_dir = 'path\to\labels'

# 目标文件夹路径
train_image_dir = r'path\to\images\train'
val_image_dir = r'path\to\images\val'
train_label_dir = r'path\to\labels\train'
val_label_dir = r'path\to\labels\val'

# 创建输出文件夹
os.makedirs(train_image_dir, exist_ok=True)
os.makedirs(val_image_dir, exist_ok=True)
os.makedirs(train_label_dir, exist_ok=True)
os.makedirs(val_label_dir, exist_ok=True)

# 获取图像文件列表
image_files = [f for f in os.listdir(images_dir) if f.lower().endswith(('.jpg', '.jpeg', '.png'))]

# 打乱并划分
random.shuffle(image_files)
split_idx = int(0.9 * len(image_files))
train_files = image_files[:split_idx]
val_files = image_files[split_idx:]

# 拷贝函数
def copy_split(file_list, img_src, lbl_src, img_dst, lbl_dst):
    for fname in file_list:
        # 拷贝图像
        shutil.copy(os.path.join(img_src, fname), os.path.join(img_dst, fname))
        # 拷贝标签
        label_name = os.path.splitext(fname)[0] + '.txt'
        label_src_path = os.path.join(lbl_src, label_name)
        label_dst_path = os.path.join(lbl_dst, label_name)
        if os.path.exists(label_src_path):
            shutil.copy(label_src_path, label_dst_path)
        else:
            print(f"⚠️ 缺少标签: {label_src_path}")

# 执行拷贝
copy_split(train_files, images_dir, labels_dir, train_image_dir, train_label_dir)
copy_split(val_files, images_dir, labels_dir, val_image_dir, val_label_dir)

print("✅ 划分完成!图像和标签已按 9:1 存放到 images/train, images/val 和 labels/train, labels/val。")
相关推荐
向哆哆5 天前
高精度织物缺陷检测数据集(适用YOLO系列/1000+标注)(已标注+划分/可直接训练)
yolo·目标检测
前网易架构师-高司机6 天前
带标注的驾驶员安全带识别数据集,识别率99.5%,可识别有无系安全带,支持yolo,coco json,pascal voc xml格式
xml·yolo·数据集·交通·安全带
向哆哆6 天前
粉尘环境分类检测千张图数据集(适用YOLO系列)(已标注+划分/可直接训练)
yolo·分类·数据挖掘
琅琊榜首20206 天前
移动端AI挂机新范式:YOLOv8+NCNN实现无Root视觉自动化
人工智能·yolo·自动化
智驱力人工智能7 天前
地铁隧道轨道障碍物实时检测方案 守护城市地下动脉的工程实践 轨道障碍物检测 高铁站区轨道障碍物AI预警 铁路轨道异物识别系统价格
人工智能·算法·yolo·目标检测·计算机视觉·边缘计算
智驱力人工智能7 天前
机场鸟类活动智能监测 守护航空安全的精准工程实践 飞鸟检测 机场鸟击预防AI预警系统方案 机场停机坪鸟类干扰实时监测机场航站楼鸟击预警
人工智能·opencv·算法·安全·yolo·目标检测·边缘计算
前端摸鱼匠7 天前
YOLOv8使用 Ultralytics 内置功能简化格式转换:介绍如何使用 yolo mode=data 等相关功能或辅助工具来加速和简化数据格式的准备工作
人工智能·yolo·目标检测·机器学习·目标跟踪·视觉检测
hans汉斯7 天前
《数据挖掘》期刊推介&征稿指南
图像处理·人工智能·算法·yolo·数据挖掘·超分辨率重建·汉斯出版社
卓越软件开发7 天前
毕设全栈开发一条龙:Java/SpringBoot/Vue/ 小程序 / Python / 安卓 / AI 图像识别 人脸检测 车牌识别 YOLO
开发语言·spring boot·python·yolo·小程序·毕业设计·课程设计
向哆哆7 天前
单车/共享单车目标检测数据集(适用YOLO系列)(已标注+划分/可直接训练)
人工智能·yolo·目标检测