当前位置: 首页 > article >正文

labelme转yolo格式

时间太悠久了,不知道代码是引用的谁的了。

首先需要将labelme文件转成json文件,这个文件包含了所有的img的内容,之前的是好几个文件,


import os
import json
import numpy as np
import glob
import shutil
np.random.seed(41)
import cv2

# 0为背景
classname_to_id = {"person": 0}

class Lableme2CoCo:

    def __init__(self, splitDir=''):
        self.images = []
        self.annotations = []
        self.categories = []
        self.img_id = 0
        self.ann_id = 0
        self.splitDir = splitDir

    def save_coco_json(self, instance, save_path):
        json.dump(instance, open(save_path, 'w', encoding='utf-8'), ensure_ascii=False, indent=1)  # indent=2 更加美观显示

    # 由json文件构建COCO
    def to_coco(self, json_path_list):
        self._init_categories()
        for json_path in json_path_list:
            # print(type(json_path))
            obj = self.read_jsonfile(json_path)
            self.images.append(self._image(obj, json_path))

            shapes = obj['shapes']
            groupIds = []
            for shape in shapes:
                groupId = shape['group_id']
                groupIds.append(groupId)
            for i in set(groupIds):
                keyPoints = [0] * 51
                keyPointNum = 0
                bbox = []

                for shape in shapes:
                    if i != shape['group_id']:
                        continue
                    if shape['shape_type'] == "point":
                        labelNum = int(shape['label'])
                        keyPoints[labelNum * 3 + 0] = int(shape['points'][0][0] + 0.5)
                        keyPoints[labelNum * 3 + 1] = int(shape['points'][0][1] + 0.5)
                        keyPoints[labelNum * 3 + 2] = 2
                        keyPointNum += 1
                    if shape['shape_type'] == 'rectangle':
                        x0, y0, x1, y1 = shape['points'][0][0], shape['points'][0][1], \
                            shape['points'][1][0], shape['points'][1][1]
                        xmin = min(x0, x1)
                        ymin = min(y0, y1)
                        xmax = max(x0, x1)
                        ymax = max(y0, y1)

                        bbox = [xmin, ymin, xmax - xmin, ymax - ymin]

                annotation = self._annotation(bbox, keyPoints, keyPointNum)
                self.annotations.append(annotation)
                self.ann_id += 1
            self.img_id += 1

            # for shape in shapes:
            #     label = shape['label']
            #     if label != 'person':
            #         continue
            #
            #     annotation = self._annotation(shape)
            #     self.annotations.append(annotation)
            #     self.ann_id += 1
            # self.img_id += 1
        instance = {}
        instance['info'] = 'spytensor created'
        instance['license'] = ['license']
        instance['images'] = self.images
        instance['annotations'] = self.annotations
        instance['categories'] = self.categories
        return instance

    # 构建类别
    def _init_categories(self):
        for k, v in classname_to_id.items():
            category = {}
            category['id'] = v
            category['name'] = k
            self.categories.append(category)

    # 构建COCO的image字段
    def _image(self, obj, jsonPath):
        image = {}
        # img_x = utils.img_b64_to_arr(obj['imageData'])
        # h, w = img_x.shape[:-1]
        jpgPath = jsonPath.replace('.json', '.jpg')
        jpgData = cv2.imread(jpgPath)
        h, w, _ = jpgData.shape

        image['height'] = h
        image['width'] = w
        image['id'] = self.img_id

        # image['file_name'] = os.path.basename(jsonPath).replace(".json", ".jpg")
        image['file_name'] = jpgPath.split(self.splitDir)[-1].replace('\\', '/')


        return image

    # 构建COCO的annotation字段
    def _annotation(self, bbox, keyPoints, keyNum):
        annotation = {}

        annotation['id'] = self.ann_id
        annotation['image_id'] = self.img_id
        annotation['category_id'] = 1
        # annotation['segmentation'] = [np.asarray(points).flatten().tolist()]
        annotation['segmentation'] = []
        annotation['bbox'] = bbox
        annotation['iscrowd'] = 0
        annotation['area'] = bbox[2] * bbox[3]
        annotation['keypoints'] = keyPoints
        annotation['num_keypoints'] = keyNum

        return annotation

    # 读取json文件,返回一个json对象
    def read_jsonfile(self, path):
        with open(path, "r", encoding='utf-8') as f:
            return json.load(f)

    # COCO的格式: [x1,y1,w,h] 对应COCO的bbox格式
    def _get_box(self, points):
        min_x = min_y = np.inf
        max_x = max_y = 0
        for x, y in points:
            min_x = min(min_x, x)
            min_y = min(min_y, y)
            max_x = max(max_x, x)
            max_y = max(max_y, y)
        return [min_x, min_y, max_x - min_x, max_y - min_y]


if __name__ == '__main__':

    labelme_path = r"D:\COCO\labelme_to_json\keypoint\train"
    print(labelme_path)
    jsonName = labelme_path.split('\\')[-1]
    saved_coco_path = r"D:\COCO\labelme_to_json\save\train"
    print(saved_coco_path)
    #####################################
    # 这个一定要注意
    # 为了方便合入coco数据, 定义截断文件的文件夹与文件名字
    splitDirFlag = 'labelMePoint\\'
    ######################################

    # 创建文件
    if not os.path.exists("%s/annotations/ " %saved_coco_path):
        os.makedirs("%s/annotations/ " %saved_coco_path)
    json_list_path = glob.glob(os.path.join(labelme_path, '*.json'))

    train_path, val_path = json_list_path, ''
    # print(train_path)
    print("train_n:", len(train_path), 'val_n:', len(val_path))

    # 把训练集转化为COCO的json格式
    l2c_train = Lableme2CoCo(splitDirFlag)
    # print(train_path)
    train_instance = l2c_train.to_coco(train_path)
    l2c_train.save_coco_json(train_instance, '%s/annotations/%s.json ' %(saved_coco_path, jsonName))

之后需要将json转成yolo格式


import json

import cv2
import pandas as pd
from PIL import Image
from collections import defaultdict

from utils import *



def convert_coco_json(cocojsonpath, savepath ,use_keypoints=False, cls91to80=True):
    """Converts COCO dataset annotations to a format suitable for training YOLOv5 models.
    Args:
        labels_dir (str, optional): Path to directory containing COCO dataset annotation files.
        use_segments (bool, optional): Whether to include segmentation masks in the output.
        use_keypoints (bool, optional): Whether to include keypoint annotations in the output.
        cls91to80 (bool, optional): Whether to map 91 COCO class IDs to the corresponding 80 COCO class IDs.
    Raises:
        FileNotFoundError: If the labels_dir path does not exist.
    Example Usage:
        convert_coco(labels_dir='../coco/annotations/', use_segments=True, use_keypoints=True, cls91to80=True)
    Output:
        Generates output files in the specified output directory.
    """
    # save_dir = make_dirs('yolo_labels')  # output directory
    save_dir = make_dirs(savepath)  # output directory
    coco80 = coco91_to_coco80_class()

    # Import json
    for json_file in sorted(Path(cocojsonpath).resolve().glob('*.json')):
        fn = Path(save_dir) / 'labels' / json_file.stem.replace('instances_', '')  # folder name
        fn.mkdir(parents=True, exist_ok=True)
        with open(json_file) as f:
            data = json.load(f)

        # Create image dict
        images = {f'{x["id"]:d}': x for x in data['images']}
        # Create image-annotations dict
        imgToAnns = defaultdict(list)
        for ann in data['annotations']:
            imgToAnns[ann['image_id']].append(ann)

        # Write labels file
        for img_id, anns in tqdm(imgToAnns.items(), desc=f'Annotations {json_file}'):
            img = images[f'{img_id:d}']
            h, w, f = img['height'], img['width'], img['file_name']

            bboxes = []
            segments = []
            keypoints = []
            for ann in anns:
                if ann['iscrowd']:
                    continue
                # The COCO box format is [top left x, top left y, width, height]
                box = np.array(ann['bbox'], dtype=np.float64)
                box[:2] += box[2:] / 2  # xy top-left corner to center
                box[[0, 2]] /= w  # normalize x
                box[[1, 3]] /= h  # normalize y
                if box[2] <= 0 or box[3] <= 0:  # if w <= 0 and h <= 0
                    continue

                cls = coco80[ann['category_id'] - 1] if cls91to80 else ann['category_id'] - 1  # class
                box = [cls] + box.tolist()
                if box not in bboxes:
                    bboxes.append(box)
                if use_keypoints and ann.get('keypoints') is not None:
                    k = (np.array(ann['keypoints']).reshape(-1, 3) / np.array([w, h, 1])).reshape(-1).tolist()
                    k = box + k
                    keypoints.append(k)

            # Write
            fname = f.split('/')[-1]
            # with open((fn / f).with_suffix('.txt'), 'a') as file:
            with open((fn / fname).with_suffix('.txt'), 'a') as file:
                for i in range(len(bboxes)):
                    if use_keypoints:
                        line = *(keypoints[i]),  # cls, box, keypoints
                    file.write(('%g ' * len(line)).rstrip() % line + '\n')
if __name__ == '__main__':
    source = 'COCO'
    cocojsonpath = r'D:\COCO\labelme_to_json\keypoint\val'
    savepath = r'D:\COCO\labelme_to_json\save\val'
    if source == 'COCO':
        convert_coco_json(cocojsonpath,  # directory with *.json
                          savepath,
                          use_keypoints=True,
                          cls91to80=True)


http://www.kler.cn/a/472219.html

相关文章:

  • Nature Electronics——近传感器计算:50 nm异构集成技术的革命
  • 【人工智能计算机视觉】——深入详解人工智能计算机视觉之图像处理之基础图像处理技术
  • 年会抽奖Html
  • 【Linux系列】并发与顺序执行:在 Linux 脚本中的应用与选择
  • (六)CAN总线通讯
  • HTML5实现喜庆的新年快乐网页源码
  • 计算机网络 (23)IP层转发分组的过程
  • R语言的循环实现
  • 前端开发 vue 中如何实现 u-form 多个form表单同时校验
  • Estimator (Statistic for Machine Learning)
  • 深入探讨 Android 中的 AlarmManager:定时任务调度及优化实践
  • AI赋能房地产:利用AI前端技术提升VR/AR浏览体验
  • IO模型与NIO基础
  • 【Uniapp-Vue3】v-if条件渲染及v-show的选择对比
  • 第07章 存储管理(一)
  • 第82期 | GPTSecurity周报
  • 基于Vite+TS初始项目 | 不断更新
  • vue 项目集成 electron 和 electron 打包及环境配置
  • 基于R语言的DICE模型
  • gitee 使用教程
  • 基于springboot线上教学平台
  • Linux 查找工具 - find 命令介绍
  • Backend - C# 操作数据库 DB(ADO.NET、LINQ to SQL、EF)
  • MyBatis SQL 映射文件基础
  • Jupyter Notebook 取消数据框(DataFrame)缩略显示
  • 02、Docker学习,理论知识,第二天:基础概念与常用命令