labelme2yolov8-seg 草稿()

简介:

最近做实例分割分割,使用Labelme生成json格式标签后,需要转换为txt标签,才能供YOLO进行训练。

在参看b站,github后,发现GitHub有相关项目:lableme2yolo

一个是ultralyics官方的JSON2YOLO项目

ultralytics/JSON2YOLO: Convert JSON annotations into YOLO format.

参考1:

将labelme数据标注格式转换为YoloV8语义分割数据集,并可自动划分训练集和验证集

python 复制代码
import json
import random
import yaml
import argparse
import shutil
from pathlib import Path
from collections import defaultdict
from tqdm import tqdm

# 设定随机种子以确保可重复性
random.seed(114514)

# yoloV8支持的图像格式
# https://docs.ultralytics.com/modes/predict/?h=format+image#images
image_formats = ["jpg", "jpeg", "png", "bmp", "webp", "tif", ".dng", ".mpo", ".pfm"]


def copy_labled_img(json_path: Path, target_folder: Path, task: str):
    # 遍历支持的图像格式,查找并复制图像文件
    for format in image_formats:
        image_path = json_path.with_suffix("." + format)
        if image_path.exists():
            # 构建目标文件夹中的目标路径
            target_path = target_folder / "images" / task / image_path.name
            shutil.copy(image_path, target_path)


def json_to_yolo(json_path: Path, sorted_keys: list):
    with open(json_path, "r") as f:
        labelme_data = json.load(f)

    width = labelme_data["imageWidth"]
    height = labelme_data["imageHeight"]
    yolo_lines = []

    for shape in labelme_data["shapes"]:
        label = shape["label"]
        points = shape["points"]
        class_idx = sorted_keys.index(label)
        txt_string = f"{class_idx} "

        for x, y in points:
            x /= width
            y /= height
            txt_string += f"{x} {y} "

        yolo_lines.append(txt_string.strip() + "\n")

    return yolo_lines


def create_directory_if_not_exists(directory_path):
    # 使用 exist_ok=True 可以避免重复检查目录是否存在
    directory_path.mkdir(parents=True, exist_ok=True)

# 创建训练使用的yaml文件
def create_yaml(output_folder: Path, sorted_keys: list):
    train_img_path = Path("images") / "train"
    val_img_path = Path("images") / "val"
    train_label_path = Path("labels") / "train"
    val_label_path = Path("labels") / "val"

    # 创建所需目录
    for path in [train_img_path, val_img_path, train_label_path, val_label_path]:
        create_directory_if_not_exists(output_folder / path)

    names_dict = {idx: name for idx, name in enumerate(sorted_keys)}
    yaml_dict = {
        "path": output_folder.as_posix(),
        "train": train_img_path.as_posix(),
        "val": val_img_path.as_posix(),
        "names": names_dict,
    }

    yaml_file_path = output_folder / "yolo.yaml"
    with open(yaml_file_path, "w") as yaml_file:
        yaml.dump(yaml_dict, yaml_file, default_flow_style=False, sort_keys=False)

    print(f"yaml created in {yaml_file_path.as_posix()}")


# Convert label to idx
def get_labels_and_json_path(input_folder: Path):
    json_file_paths = list(input_folder.rglob("*.json"))
    label_counts = defaultdict(int)

    for json_file_path in json_file_paths:
        with open(json_file_path, "r") as f:
            labelme_data = json.load(f)
        for shape in labelme_data["shapes"]:
            label = shape["label"]
            label_counts[label] += 1
    
    # 根据标签出现次数排序标签
    sorted_keys = sorted(label_counts, key=lambda k: label_counts[k], reverse=True)
    return sorted_keys, json_file_paths


def labelme_to_yolo(
    json_file_paths: list, output_folder: Path, sorted_keys: list, split_rate: float
):
    # 随机打乱 JSON 文件路径列表
    random.shuffle(json_file_paths)

    # 计算训练集和验证集的分割点
    split_point = int(split_rate * len(json_file_paths))
    train_set = json_file_paths[:split_point]
    val_set = json_file_paths[split_point:]

    for json_file_path in tqdm(train_set):
        txt_name = json_file_path.with_suffix(".txt").name
        yolo_lines = json_to_yolo(json_file_path, sorted_keys)
        output_json_path = Path(output_folder / "labels" / "train" / txt_name)
        with open(output_json_path, "w") as f:
            f.writelines(yolo_lines)
        copy_labled_img(json_file_path, output_folder, task="train")

    for json_file_path in tqdm(val_set):
        txt_name = json_file_path.with_suffix(".txt").name
        yolo_lines = json_to_yolo(json_file_path, sorted_keys)
        output_json_path = Path(output_folder / "labels" / "val" / txt_name)
        with open(output_json_path, "w") as f:
            f.writelines(yolo_lines)
        copy_labled_img(json_file_path, output_folder, task="val")


if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="labelme2yolo")
    parser.add_argument("input_folder", help="输入LabelMe格式文件的文件夹")
    parser.add_argument("output_folder", help="输出YOLO格式文件的文件夹")
    parser.add_argument("split_rate", help="调整训练集和测试集的比重")

    args = parser.parse_args()
    input_folder = Path(args.input_folder)
    output_folder = Path(args.output_folder)
    split_rate = float(args.split_rate)

    sorted_keys, json_file_paths = get_labels_and_json_path(input_folder)
    create_yaml(output_folder, sorted_keys)
    labelme_to_yolo(json_file_paths, output_folder, sorted_keys, split_rate)

参考资料

1.参考1:KdaiP/labelme2YoloV8-segment: 将labelme数据标注格式转换为YoloV8语义分割数据集,并可自动划分训练集和验证集

2.rooneysh/Labelme2YOLO: 帮助将 LabelMe 注释工具 JSON 格式转换为 YOLO 文本文件格式。如果您已经通过 LabelMe 标记了分割数据集,则可以轻松使用此工具来帮助转换为 YOLO 格式的数据集。

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