labelme标签格式json转化成yolov8支持是数据集格式

news2024/11/16 17:55:34

 我们用yolov8做实例分割时,需要制作标签,如果用labelme做,不能直接用模型训练,需要利用一个脚本文件进行转换。

import base64
import random
import shutil
from tqdm import tqdm
import math
import json
import os
import numpy as np
import PIL.Image
import PIL.ImageDraw
import cv2


class ConvertManager(object):
    def __init__(self):
        pass

    def base64_to_numpy(self, img_bs64):
        img_bs64 = base64.b64decode(img_bs64)
        img_array = np.frombuffer(img_bs64, np.uint8)
        cv2_img = cv2.imdecode(img_array, cv2.IMREAD_COLOR)
        return cv2_img

    @classmethod
    def load_labels(cls, name_file):
        '''
        load names from file.one name one line
        :param name_file:
        :return:
        '''
        with open(name_file, 'r') as f:
            lines = f.read().rstrip('\n').split('\n')
        return lines

    def get_class_names_from_all_json(self, json_dir):
        classnames = []
        for file in os.listdir(json_dir):
            if not file.endswith('.json'):
                continue
            with open(os.path.join(json_dir, file), 'r', encoding='utf-8') as f:
                data_dict = json.load(f)
                for shape in data_dict['shapes']:
                    if not shape['label'] in classnames:
                        classnames.append(shape['label'])
        return classnames

    def create_save_dir(self, save_dir):
        images_dir = os.path.join(save_dir, 'images')
        labels_dir = os.path.join(save_dir, 'labels')
        if not os.path.exists(save_dir):
            os.makedirs(save_dir)
            os.mkdir(images_dir)
            os.mkdir(labels_dir)
        else:
            if not os.path.exists(images_dir):
                os.mkdir(images_dir)
            if not os.path.exists(labels_dir):
                os.mkdir(labels_dir)
        return images_dir + os.sep, labels_dir + os.sep

    def save_list(self, data_list, save_file):
        with open(save_file, 'w') as f:
            f.write('\n'.join(data_list))

    def __rectangle_points_to_polygon(self, points):
        xmin = 0
        ymin = 0
        xmax = 0
        ymax = 0
        if points[0][0] > points[1][0]:
            xmax = points[0][0]
            ymax = points[0][1]
            xmin = points[1][0]
            ymin = points[1][1]
        else:
            xmax = points[1][0]
            ymax = points[1][1]
            xmin = points[0][0]
            ymin = points[0][1]
        return [[xmin, ymin], [xmax, ymin], [xmax, ymax], [xmin, ymax]]

    def convert_dataset(self, json_dir, json_list, images_dir, labels_dir, names, save_mode='train'):
        images_dir = os.path.join(images_dir, save_mode)+os.sep
        labels_dir = os.path.join(labels_dir, save_mode)+os.sep
        if not os.path.exists(images_dir):
            os.mkdir(images_dir)
        if not os.path.exists(labels_dir):
            os.mkdir(labels_dir)
        for file in tqdm(json_list):
            with open(os.path.join(json_dir, file), 'r', encoding='utf-8') as f:
                data_dict = json.load(f)
            image_file = os.path.join(json_dir, os.path.basename(data_dict['imagePath']))
            if os.path.exists(image_file):
                shutil.copyfile(image_file, images_dir + os.path.basename(image_file))
            else:
                imageData = data_dict.get('imageData')
                if not imageData:
                    imageData = base64.b64encode(imageData).decode('utf-8')
                    img = self.img_b64_to_arr(imageData)
                    PIL.Image.fromarray(img).save(images_dir + file[:-4] + 'png')
            # convert to txt
            width = data_dict['imageWidth']
            height = data_dict['imageHeight']
            line_list = []
            for shape in data_dict['shapes']:
                data_list = []
                data_list.append(str(names.index(shape['label'])))
                if shape['shape_type'] == 'rectangle':
                    points = self.__rectangle_points_to_polygon(shape['points'])
                    for point in points:
                        data_list.append(str(point[0] / width))
                        data_list.append(str(point[1] / height))


                elif shape['shape_type'] == 'polygon':
                    points = shape['points']
                    for point in points:
                        data_list.append(str(point[0] / width))
                        data_list.append(str(point[1] / height))
                line_list.append(' '.join(data_list))

            self.save_list(line_list, labels_dir + file[:-4] + "txt")

    def split_train_val_test_dataset(self, file_list, train_ratio=0.9, trainval_ratio=0.9, need_test_dataset=False,
                                     shuffle_list=True):
        if shuffle_list:
            random.shuffle(file_list)
        total_file_count = len(file_list)
        train_list = []
        val_list = []
        test_list = []
        if need_test_dataset:
            trainval_count = int(total_file_count * trainval_ratio)
            trainval_list = file_list[:trainval_count]
            test_list = file_list[trainval_count:]
            train_count = int(train_ratio * len(trainval_list))
            train_list = trainval_list[:train_count]
            val_list = trainval_list[train_count:]
        else:
            train_count = int(train_ratio * total_file_count)
            train_list = file_list[:train_count]
            val_list = file_list[train_count:]
        return train_list, val_list, test_list

    def start(self, json_dir, save_dir, names=None, train_ratio=0.9):
        images_dir, labels_dir = self.create_save_dir(save_dir)
        if names is None or len(names) == 0:
            print('class names will load from all json file')
            names = self.get_class_names_from_all_json(json_dir)
        print('find {} class names :'.format(len(names)), names)
        if len(names) == 0:
            return

        self.save_list(names, os.path.join(save_dir, 'labels.txt'))
        print('start convert')
        all_json_list = []
        for file in os.listdir(json_dir):
            if not file.endswith('.json'):
                continue
            all_json_list.append(file)
        train_list, val_list, test_list = self.split_train_val_test_dataset(all_json_list, train_ratio)
        self.convert_dataset(json_dir, train_list, images_dir, labels_dir, names, 'train')
        self.convert_dataset(json_dir, val_list, images_dir, labels_dir, names, 'val')


if __name__ == '__main__':
    cm = ConvertManager()
    cm.start(r'源文件路径', r'保存新位置路径')

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/807590.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

5.2.12.读写接口实践 copy_from_user copy_to_user

5.2.12.读写接口实践 5.2.12.1、完成write和read函数 (1)copy_from_user函数的返回值定义,和常规有点不同。返回值如果成功复制则返回0,如果 不成功复制则返回尚未成功复制剩下的字节数。 copy_from_user 函数:static inline unsigned long _…

【业务功能篇59】Springboot + Spring Security 权限管理 【下篇】

UserDetails接口定义了以下方法: getAuthorities(): 返回用户被授予的权限集合。这个方法返回的是一个集合类型,其中每个元素都是一个GrantedAuthority对象,表示用户被授予的权限。getPassword(): 返回用户的密码。这个方法返回的是一个字符…

第十二章:priority_queue类

系列文章目录 文章目录 系列文章目录前言priority_queue的介绍priority_queue的使用容器适配器什么是容器适配器STL标准库中stack和queue的底层结构 总结 前言 priority_queue是容器适配器,底层封装了STL容器。 priority_queue的介绍 priority_queue文档介绍 优先…

路由器工作原理

路由器原理 路由概述 路由:跨越从源主机到目标主机的一个互联网络来转发数据包的过程。(为数据包选择路径的过程) 作用:路由器是连接不同网段的。 转发依据: 路由表:路径选择全看路由表,根…

大数据课程D5——hadoop的Sink

文章作者邮箱:yugongshiyesina.cn 地址:广东惠州 ▲ 本章节目的 ⚪ 掌握Sink的HDFS Sink; ⚪ 掌握Sink的Logger Sink; ⚪ 掌握Sink的File Roll Sink; ⚪ 掌握Sink的Null Sink; ⚪ 掌握Si…

【前端知识】React 基础巩固(三十六)——RTK中的异步操作

React 基础巩固(三十六)——RTK中的异步操作 一、RTK中使用异步操作 引入RTK中的createAsyncThunk,在extraReducers中监听执行状态 import { createSlice, createAsyncThunk } from "reduxjs/toolkit"; import axios from "axios";export cons…

<MySQL> Centos 7环境安装MySQL

Centos 7环境安装MySQL 1.卸载不要的环境 停止MySQL服务 systemctl stop mariadb.service systemctl stop mysqld禁止MySQL服务开机自启 systemctl disable mysqld卸载MySQL软件包 yum remove mysql-server mysql-client删除MySQL数据目录 rm -rf /var/lib/mysql清理MySQ…

福特汽车在全球电动汽车市场的主导地位正在不断扩大

来源:猛兽财经 作者:猛兽财经 2023年7月27日,美国最大的汽车巨头之一福特汽车(F)公布了其2023年第二季度财报。 2023年7月6日,福特汽车宣布,第二季度美国市场的汽车销量已经较2023年第一季度增长了11.7%,令…

机器人状态估计:robot_localization 功能包高级参数详解

机器人状态估计:robot_localization 功能包高级参数详解 前言功能包简介相关参数高级参数 前言 移动机器人的状态估计需要用到很多传感器,因为对单一的传感器来讲,都存在各自的优缺点,所以需要一种多传感器融合技术,将…

微信朋友圈跟圈怎么设置?

朋友圈跟发功能对需要进行朋友圈营销或微信营销的公司和个体创业者的帮助极大。通常情况下,这些创业者或企业会管理多个微信账号来协同运营和管理客户资源,也就是俗称的“大号”和“小号”。如果没有朋友圈跟发软件,客户需要依次使用大号来发…

141. 环形链表

简单 1.9K 相关企业 给你一个链表的头节点 head ,判断链表中是否有环。 如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链…

十九章:利用跨图像语义挖掘进行弱监督语义分割

0.摘要 本文研究了仅使用图像级别监督进行语义分割学习的问题。目前流行的解决方案利用分类器的对象定位图作为监督信号,并努力使定位图捕捉更完整的对象内容。与之前主要关注于图像内部信息的努力不同,我们着眼于跨图像语义关系在全面对象模式挖掘中的价…

冯诺依曼体系的认识、来源、原理、组成、功能和特点

目录 一.认识冯诺依曼 二.冯诺依曼体系结构的来源 三.冯诺依曼体系结构计算机 3.1工作原理 3.2组成部件 3.3功能和特点 🎁个人主页:tq02的博客_CSDN博客-C语言,Java,Java数据结构领域博主 🎥 本文由 tq02 原创,首发于 CSDN&…

股票回购不积极,遭分析师看空,汽车之家财务前景黯淡

来源:猛兽财经 作者:猛兽财经 第一季度财报后股价表现不佳 汽车之家(ATHM)于2023年5月11日公布了2023年第一季度业财报绩。 猛兽财经通过查询财报得知,汽车之家第一季度的实际营收为2.21亿美元,正常每股收…

java可变字符序列:StringBuffer、StringBuilder

文章目录 StringBuffer与StringBuilder的理解StringBuilder、StringBuffer的API StringBuffer与StringBuilder的理解 因为String对象是不可变对象,虽然可以共享常量对象,但是对于频繁字符串的修改和拼接操作,效率极低,空间消耗也…

【算法训练营】Fibonacci数列+合法括号序列判断+两种排序方法

7.29 Fibonacci数列题目解析代码 合法括号序列判断题目题解代码 两种排序方法题目:题解代码 Fibonacci数列 题目 题目链接: 点击跳转 解析 【题目解析】: 本题是对于Fibonacci数列的一个考察,Fibonacci数列的性质是第一项和第二项都为1&am…

Segmentation fault 利用 core.xxx文件帮助你debug

在没有get到本文介绍的技能之前的时候,以前遇到程序发生了 Segmentation fault 时,也是一筹莫展,看到伴随程序崩溃而生成的 core.xxxx 文件时(有时会生成,有时不会生成,留着下面介绍)&#xff0…

SpringBoot2.2.0.RELEASE整合Elasticsearch6.8.3

SpringBoot2.2.0.RELEASE整合Elasticsearch6.8.3 SpringBoot是2.2.0.RELEASE&#xff0c;elasticsearch是6.8.3 使用依赖spring-boot-starter-data-elasticsearch 使用ElasticSearchRepository操作 1、导入依赖 <?xml version"1.0" encoding"UTF-8&quo…

24考研数据结构-数组和特殊矩阵

目录 数据结构&#xff1a;数组与特殊矩阵数组数组的特点数组的用途 特殊矩阵对角矩阵上三角矩阵和下三角矩阵稀疏矩阵特殊矩阵的用途 结论 3.4 数组和特殊矩阵3.4.1数组的存储结构3.4.2普通矩阵的存储3.4.3特殊矩阵的存储1. 对称矩阵(方阵)2. 三角矩阵(方阵)3. 三对角矩阵(方阵…

Meta-Transformer 多模态学习的统一框架

Meta-Transformer是一个用于多模态学习的新框架&#xff0c;用来处理和关联来自多种模态的信息&#xff0c;如自然语言、图像、点云、音频、视频、时间序列和表格数据&#xff0c;虽然各种数据之间存在固有的差距&#xff0c;但是Meta-Transformer利用冻结编码器从共享标记空间…