YOLO数据集制作(三)|Labelme标注的“多边形框”json文件转txt

以下教程用于将使用Labelme软件标注生成的json格式文件转成YOLO使用的txt格式,适用场景:多边形框

        使用方法:将json文件夹路径填到jsonfilePath后, 将保存转化后txt的路径填入resultDirPath后,运行即可转化。

import json
import os
from tqdm import tqdm
import glob
import os.path as osp


# 参考链接 https://blog.csdn.net/m0_63330473/article/details/135079898
# 适应场景:lableme标注软件生成的json实例分割标签转yolo适用的txt格式


def json_to_txt(jsonfilePath, resultDirPath, ):
    """
    jsonfilePath: labelme标注好的*.json文件所在文件夹
    resultDirPath: 转换好后的*.txt保存文件夹
    classList: 数据集中的类别标签
    """

    class_names=[]

    jsonfileList = glob.glob(osp.join(jsonfilePath, "*.json"))

    # for jsonfile in jsonfileList:
    # for jsonfile in jsonfileList:
    for jsonfile in tqdm(jsonfileList, desc='Processing'):

        with open(jsonfile, "r", encoding='UTF-8') as f:
            file_in = json.load(f)

            # 4. 读取文件中记录的所有标注目标
            shapes = file_in["shapes"]

            # 5. 使用图像名称创建一个txt文件,用来保存数据
            with open(resultDirPath + "\\" + jsonfile.split("\\")[-1].replace(".json", ".txt"), "w") as file_handle:
                # 6. 遍历shapes中的每个目标的轮廓
                for shape in shapes:
                    if shape["label"] not in class_names:
                        class_names.append(shape["label"])
                    # 7.根据json中目标的类别标签,从classList中寻找类别的ID,然后写入txt文件中
                    file_handle.writelines(str(class_names.index(shape["label"])) + " ")

                    # 8. 遍历shape轮廓中的每个点,每个点要进行图像尺寸的缩放,即x/width, y/height
                    for point in shape["points"]:
                        x = point[0] / file_in["imageWidth"]  # mask轮廓中一点的X坐标
                        y = point[1] / file_in["imageHeight"]  # mask轮廓中一点的Y坐标
                        file_handle.writelines(str(x) + " " + str(y) + " ")  # 写入mask轮廓点

                    file_handle.writelines("\n")
            file_handle.close()
        f.close()
    with open(resultDirPath + '\\' + 'classes.txt', 'w') as f:
        for i in class_names:
            f.write(i + '\n')


if __name__ == "__main__":
    jsonfilePath = r"O:\DeepLearningTool\dataset\segment\image"  # 要转换的json文件所在目录
    resultDirPath = r"O:\DeepLearningTool\dataset\segment\label"  # 要生成的txt文件夹
    json_to_txt(jsonfilePath=jsonfilePath, resultDirPath=resultDirPath,)

### 将LabelMe生成的多边形JSON文件换为YOLO支持的数据格式 为了将LabelMe生成的多边形JSON文件换为YOLO支持的数据格式,需要遵循特定的步骤和逻辑。以下是详细的说明: #### 数据准备 在开始之前,需确认已安装必要的库并准备好数据集。通常情况下,需要用到`labelme`库以及一些标准的Python库如`numpy`和`opencv-python`。 #### 换过程概述 1. **解析JSON文件**:读取由LabelMe生成的JSON文件内容。 2. **提取形状信息**:从JSON中获取标注对象的形状(通常是多边形)及其类别名称。 3. **计算边界坐标**:对于每个多边形,计算其最小外接矩形,并将其标准化到YOLO所需的相对坐标系下。 4. **保存为TXT文件**:按照YOLO的标准格式写入目标文件。 #### 关键技术细节 - YOLO格式要求每一行表示一个物体检测的信息,具体形式如下: ``` <class_id> <x_center> <y_center> <width> <height> ``` 其中 `<class_id>` 是类别的索引号;其余四个参数均为相对于图像宽度或高度的比例值[^1]。 - 对于多边形标注,可以通过OpenCV中的 `cv2.boundingRect()` 函数快速获得包围该多边形的最小矩形区域[^3]。 #### 实现代码示例 下面提供了一个完整的Python脚本来完成上述任务: ```python import os import cv2 import numpy as np from labelme import utils def shape_to_yolo(shape, img_shape): points = np.array([point for point in shape['points']]) rect = cv2.boundingRect(points) x_min, y_min, width, height = rect image_height, image_width = img_shape[:2] # Normalize to [0, 1] x_center = (x_min + width / 2) / image_width y_center = (y_min + height / 2) / image_height norm_width = width / image_width norm_height = height / image_height return x_center, y_center, norm_width, norm_height def convert_labelme_json_to_yolo(json_file, class_name_to_id, output_dir): data = utils.json.load(open(json_file)) img_path = os.path.join(os.path.dirname(json_file), data["imagePath"]) img = utils.img_b64_to_arr(data["imageData"]) if "imageData" in data else cv2.imread(img_path) txt_output = [] for shape in data['shapes']: cls_name = shape['label'] if cls_name not in class_name_to_id: continue cls_id = class_name_to_id[cls_name] bbox_info = shape_to_yolo(shape, img.shape) line = f"{cls_id} {' '.join(map(str, bbox_info))}" txt_output.append(line) base_name = os.path.splitext(os.path.basename(json_file))[0] with open(f"{output_dir}/{base_name}.txt", 'w') as f: f.write("\n".join(txt_output)) if __name__ == "__main__": json_files = ["path/to/json/file"] classes = {"object_class": 0} out_dir = "./labels" os.makedirs(out_dir, exist_ok=True) for jf in json_files: convert_labelme_json_to_yolo(jf, classes, out_dir) ``` 以上代码实现了从单个LabelMe JSON文件YOLO TXT文件换功能[^2]。 #### 注意事项 - 需要提前定义好类别映射字典`class_name_to_id`以便正确分配每个标签对应的ID编号。 - 如果存在多个JSON文件,则应循环调用函数处理每一个文件。 - 输出目录应当预先创建以免发生错误。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值