yolov8训练数据集——labelme的json文件转txt文件

yolov8的环境搭建,参考:Home - Ultralytics YOLO Docs

1.把标注好的json文件和jpg放同一个目录下。

2.运行转换脚本文件labelme2yolo.py文件:

# -*- coding: utf-8 -*-import os
import numpy as np
import json
from glob import glob
import cv2
import shutil
import yaml
from sklearn.model_selection import train_test_split
from tqdm import tqdm
from PIL import Image'''
统一图像格式
'''
def change_image_format(label_path, suffix='.jpg'):"""统一当前文件夹下所有图像的格式,如'.jpg':param suffix: 图像文件后缀:param label_path:当前文件路径:return:"""externs = ['png', 'jpg', 'JPEG', 'BMP', 'bmp']files = list()# 获取尾缀在ecterns中的所有图像for extern in externs:files.extend(glob(label_path + "\\*." + extern))# 遍历所有图像,转换图像格式for index,file in enumerate(tqdm(files)):name = ''.join(file.split('.')[:-1])file_suffix = file.split('.')[-1]if file_suffix != suffix.split('.')[-1]:# 重命名为jpgnew_name = name + suffix# 读取图像image = Image.open(file)image = cv2.cvtColor(np.asarray(image), cv2.COLOR_RGB2BGR)# 重新存图为jpg格式cv2.imwrite(new_name, image)# 删除旧图像os.remove(file)'''
读取所有json文件,获取所有的类别
'''
def get_all_class(file_list, label_path):"""从json文件中获取当前数据的所有类别:param file_list:当前路径下的所有文件名:param label_path:当前文件路径:return:"""# 初始化类别列表classes = list()# 遍历所有json,读取shape中的label值内容,添加到classesfor filename in tqdm(file_list):json_path = os.path.join(label_path, filename + '.json')json_file = json.load(open(json_path, "r", encoding="utf-8"))for item in json_file["shapes"]:label_class = item['label']if label_class not in classes:classes.append(label_class)print('read file done')return classes'''
划分训练集、验证机、测试集
'''
def split_dataset(label_path, test_size=0.3, isUseTest=False, useNumpyShuffle=False):"""将文件分为训练集,测试集和验证集:param useNumpyShuffle: 使用numpy方法分割数据集:param test_size: 分割测试集或验证集的比例:param isUseTest: 是否使用测试集,默认为False:param label_path:当前文件路径:return:"""# 获取所有jsonfiles = glob(label_path + "\\*.json")files = [i.replace("\\", "/").split("/")[-1].split(".json")[0] for i in files]if useNumpyShuffle:file_length = len(files)index = np.arange(file_length)np.random.seed(32)np.random.shuffle(index) # 随机划分test_files = None# 是否有测试集if isUseTest:trainval_files, test_files = np.array(files)[index[:int(file_length * (1 - test_size))]], np.array(files)[index[int(file_length * (1 - test_size)):]]else:trainval_files = files# 划分训练集和测试集train_files, val_files = np.array(trainval_files)[index[:int(len(trainval_files) * (1 - test_size))]], \np.array(trainval_files)[index[int(len(trainval_files) * (1 - test_size)):]]else:test_files = Noneif isUseTest:trainval_files, test_files = train_test_split(files, test_size=test_size, random_state=55)else:trainval_files = filestrain_files, val_files = train_test_split(trainval_files, test_size=test_size, random_state=55)return train_files, val_files, test_files, files'''
生成yolov8的训练、验证、测试集的文件夹
'''
def create_save_file(ROOT_DIR):print('step6:生成yolov8的训练、验证、测试集的文件夹')# 生成训练集train_image = os.path.join(ROOT_DIR, 'images','train')if not os.path.exists(train_image):os.makedirs(train_image)train_label = os.path.join(ROOT_DIR, 'labels','train')if not os.path.exists(train_label):os.makedirs(train_label)# 生成验证集val_image = os.path.join(ROOT_DIR, 'images', 'val')if not os.path.exists(val_image):os.makedirs(val_image)val_label = os.path.join(ROOT_DIR, 'labels', 'val')if not os.path.exists(val_label):os.makedirs(val_label)# 生成测试集test_image = os.path.join(ROOT_DIR, 'images', 'test')if not os.path.exists(test_image):os.makedirs(test_image)test_label = os.path.join(ROOT_DIR, 'labels', 'test')if not os.path.exists(test_label):os.makedirs(test_label)return train_image, train_label, val_image, val_label, test_image, test_label'''
转换,根据图像大小,返回box框的中点和高宽信息
'''
def convert(size, box):# 宽dw = 1. / (size[0])# 高dh = 1. / (size[1])x = (box[0] + box[1]) / 2.0 - 1y = (box[2] + box[3]) / 2.0 - 1# 宽w = box[1] - box[0]# 高h = box[3] - box[2]x = x * dww = w * dwy = y * dhh = h * dhreturn x, y, w, h'''
移动图像和标注文件到指定的训练集、验证集和测试集中
'''
def push_into_file(file, images, labels, ROOT_DIR, suffix='.jpg'):"""最终生成在当前文件夹下的所有文件按image和label分别存在到训练集/验证集/测试集路径的文件夹下:param file: 文件名列表:param images: 存放images的路径:param labels: 存放labels的路径:param label_path: 当前文件路径:param suffix: 图像文件后缀:return:"""# 遍历所有文件for filename in tqdm(file):# 图像文件image_file = os.path.join(ROOT_DIR, filename + suffix)# 标注文件label_file = os.path.join(ROOT_DIR, filename + '.txt')# yolov8存放图像文件夹if not os.path.exists(os.path.join(images, filename + suffix)):try:shutil.move(image_file, images)except OSError:pass# yolov8存放标注文件夹if not os.path.exists(os.path.join(labels, filename + suffix)):try:shutil.move(label_file, labels)except OSError:pass''''''
def json2txt(classes, txt_Name='allfiles', ROOT_DIR="", suffix='.jpg'):"""将json文件转化为txt文件,并将json文件存放到指定文件夹:param classes: 类别名:param txt_Name:txt文件,用来存放所有文件的路径:param label_path:当前文件路径:param suffix:图像文件后缀:return:"""store_json = os.path.join(ROOT_DIR, 'json')if not os.path.exists(store_json):os.makedirs(store_json)_, _, _, files = split_dataset(ROOT_DIR)if not os.path.exists(os.path.join(ROOT_DIR, 'tmp')):os.makedirs(os.path.join(ROOT_DIR, 'tmp'))list_file = open(os.path.join(ROOT_DIR,'tmp/%s.txt'% txt_Name) , 'w')for json_file_ in tqdm(files):# json路径json_filename = os.path.join(ROOT_DIR, json_file_ + ".json")# 图像路径imagePath = os.path.join(ROOT_DIR, json_file_ + suffix)# 写入图像文件夹路径list_file.write('%s\n' % imagePath)# 转换后txt标签文件夹路径out_file = open('%s/%s.txt' % (ROOT_DIR, json_file_), 'w')# 加载标签json文件json_file = json.load(open(json_filename, "r", encoding="utf-8"))'''核心:标签转换(json转txt)'''if os.path.exists(imagePath):height, width, channels = cv2.imread(imagePath).shapefor multi in json_file["shapes"]:if len(multi["points"][0]) == 0:out_file.write('')continuepoints = np.array(multi["points"])xmin = min(points[:, 0]) if min(points[:, 0]) > 0 else 0xmax = max(points[:, 0]) if max(points[:, 0]) > 0 else 0ymin = min(points[:, 1]) if min(points[:, 1]) > 0 else 0ymax = max(points[:, 1]) if max(points[:, 1]) > 0 else 0label = multi["label"]if xmax <= xmin:passelif ymax <= ymin:passelse:cls_id = classes.index(label)b = (float(xmin), float(xmax), float(ymin), float(ymax))bb = convert((width, height), b)out_file.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n')# print(json_filename, xmin, ymin, xmax, ymax, cls_id)if not os.path.exists(os.path.join(store_json, json_file_ + '.json')):try:shutil.move(json_filename, store_json)except OSError:pass'''
创建yaml文件
'''
def create_yaml(classes, ROOT_DIR, isUseTest=False,dataYamlName=""):print('step5:创建yolov8训练所需的yaml文件')classes_dict = {}for index, item in enumerate(classes):classes_dict[index] = itemif not isUseTest:desired_caps = {'path': ROOT_DIR,'train': 'images/train','val': 'images/val','names': classes_dict}else:desired_caps = {'path': ROOT_DIR,'train': 'images/train','val': 'images/val','test': 'images/test','names': classes_dict}yamlpath = os.path.join(ROOT_DIR, dataYamlName + ".yaml")# 写入到yaml文件with open(yamlpath, "w+", encoding="utf-8") as f:for key, val in desired_caps.items():yaml.dump({key: val}, f, default_flow_style=False)# 首先确保当前文件夹下的所有图片统一后缀,如.jpg,如果为其他后缀,将suffix改为对应的后缀,如.png
def ChangeToYoloDet(ROOT_DIR="", suffix='.bmp',classes="", test_size=0.1, isUseTest=False,useNumpyShuffle=False,auto_genClasses = False,dataYamlName=""):"""生成最终标准格式的文件:param test_size: 分割测试集或验证集的比例:param label_path:当前文件路径:param suffix: 文件后缀名:param isUseTest: 是否使用测试集:return:"""# step1:统一图像格式change_image_format(ROOT_DIR)# step2:根据json文件划分训练集、验证集、测试集train_files, val_files, test_file, files = split_dataset(ROOT_DIR, test_size=test_size, isUseTest=isUseTest)# step3:根据json文件,获取所有类别classes = classes# 是否自动从数据集中获取类别数if auto_genClasses:classes = get_all_class(files, ROOT_DIR)'''step4:(***核心***)将json文件转化为txt文件,并将json文件存放到指定文件夹'''json2txt(classes, txt_Name='allfiles', ROOT_DIR=ROOT_DIR, suffix=suffix)# step5:创建yolov8训练所需的yaml文件create_yaml(classes, ROOT_DIR, isUseTest=isUseTest,dataYamlName=dataYamlName)# step6:生成yolov8的训练、验证、测试集的文件夹train_image_dir, train_label_dir, val_image_dir, val_label_dir, test_image_dir, test_label_dir = create_save_file(ROOT_DIR)# step7:将所有图像和标注文件,移动到对应的训练集、验证集、测试集# 将文件移动到训练集文件中push_into_file(train_files, train_image_dir, train_label_dir,ROOT_DIR=ROOT_DIR, suffix=suffix)# 将文件移动到验证集文件夹中push_into_file(val_files, val_image_dir, val_label_dir,ROOT_DIR=ROOT_DIR,  suffix=suffix)# 如果测试集存在,则将文件移动到测试集文件中if test_file is not None:push_into_file(test_file, test_image_dir, test_label_dir, ROOT_DIR=ROOT_DIR, suffix=suffix)print('create dataset done')if __name__ == "__main__":'''1.ROOT_DIR:图像和json标签的路径2.suffix:统一图像尾缀3.classes=['dog', 'cat'],  # 输入你标注的列表里的名称(注意区分大小写),用于自定义类别名称和id对应4.test_size:测试集和验证集所占比例5.isUseTest:是否启用测试集6.useNumpyShuffle:是否随机打乱7.auto_genClasses:是否自动根据json标签生成类别列表8.dataYamlName:数据集yaml文件名称'''ChangeToYoloDet(ROOT_DIR = r'C:\Users\WYX\Desktop\code\matlab-code\LW\images', # 注意数据集路径不要含中文suffix='.jpg',  # 确定图像尾缀,用于统一图像尾缀classes=['whistlewave'],  # 输入你标注的列表里的名称(注意区分大小写)test_size=0.1,  # 测试集大小占比isUseTest=True,  # 是否启用测试集useNumpyShuffle=False,   # 是否乱序auto_genClasses = False,  # 是否根据数据集自动生成类别iddataYamlName= "whistlewave_data" # 数据集yaml文件名称)

3.配置文件

设置数据集路径(含有图片和json文件):

 ROOT_DIR = r'C:\Users\WYX\Desktop\code\matlab-code\LW\images', # 注意数据集路径不要含中文

设置标注标签信息的类别:

classes=['whistlewave'],  # 输入你标注的列表里的名称(注意区分大小写)

设置数据集yaml文件名称,运行代码后会在数据集文件夹下生成yaml文件:

 dataYamlName= "whistlewave_data" # 数据集yaml文件名称

运行代码会自动在数据集下创建images、json、labels、tmp文件夹,并会创建yaml文件,文件结构:

 

4.转换的标注文件样式

 0 :标签类别

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【C#】CacheManager:高效的 .NET 缓存管理库

在现代应用开发中&#xff0c;缓存是提升性能和降低数据库负载的重要技术手段。无论是 Web 应用、桌面应用还是移动应用&#xff0c;缓存都能够帮助减少重复的数据查询和处理&#xff0c;从而提高系统的响应速度。然而&#xff0c;管理缓存并不简单&#xff0c;尤其是当你需要处…

Linux-基础实操篇-组管理和权限管理(上)

Linux 组基本介绍 在 linux 中的每个用户必须属于一个组&#xff0c;不能独立于组外。在 linux 中每个文件 有所有者、所在组、其它组的概念。 用户和组的基本概念&#xff1a; 用户名&#xff1a;用来识别用户的名称&#xff0c;可以是字母、数字组成的字符串&#xff0…

基于yolo11的工地钢筋检测计数训练、应用系统

基于yolo11的工地钢筋检测计数应用系统 基于yolo11的工地钢筋检测计数训练系统 yolov8/9/10/11模型在工地钢筋检测计数中的应用【代码数据集python环境训练/应用GUI系统】 背景意义 多数钢厂和工地普遍依靠人工来统计成捆钢筋的根数&#xff0c;这种方式不仅机械枯燥、劳动强度…

深入掌握 Protobuf 与 RPC 的高效结合:实现C++工程中的高效通信

目录 一、Protobuf与RPC框架的通信流程概述二、Protobuf与RPC在C中的实际应用2.1 定义 .proto 文件2.2 编译 .proto 文件生成C代码2.3 实现服务器端逻辑2.4 实现客户端逻辑2.5 使用CMake构建工程2.6 编译与运行2.7 关键组件解析2.8 序列化与反序列化的实现 三、关键实现与解析四…

帝都程序猿十二时辰

前言 2019年度国产剧《长安十二时辰》火了&#xff0c;其口碑榜首、节奏紧凑、贴合原著、电影质感&#xff0c;都是这部剧的亮点。而最令人震撼的还是剧中对大唐盛世的还原&#xff0c;长安街坊的市容市貌、长安百姓的生活日常、长安风情的美轮美奂……而关于十二时辰的话题也接…

Unity 2D RPG Kit 学习笔记

学习资料&#xff1a; B站教学视频&#xff1a;https://www.bilibili.com/video/BV1dC4y1o7A5?p1&vd_source707ec8983cc32e6e065d5496a7f79ee6 2D RPG Kit Documentation.pdf文档 1、2D RPG Kit Documentation文档 1.1、Scenes/TitleScreen 开始菜单工程 1.2、https://it…

C++语言学习(3): type 的概念

type 的概念 C中的变量拥有类型&#xff0c; 这是显然的。 实际上&#xff0c;每个 object&#xff0c; 每个 reference&#xff0c; 每个 function&#xff0c; 每个 expression &#xff0c; 都有对应的 type &#xff08;类型&#xff09;&#xff1a; Each object, refer…

【SQL】有至少五名直接下属的经理

目录 语法 需求 示例 分析 代码 语法 SELECT columns FROM table1 JOIN table2 ON table1.common_column table2.common_column; 在数据库管理和编程中&#xff0c;JOIN 是一种用于结合来自两个或多个表的数据的 SQL 操作。通过使用 JOIN&#xff0c;你可以根据两个表中的…

vue3 + ts 二次封装 el-menu

实现效果&#xff1a; 1. types / menu.ts export interface MenuItem {index: string,label: string,icon?: string,disabled?: boolean,children?: MenuItem[], }2. components / CustomMenu / index.vue <template><el-menu :default-active"defaultActi…

10.2 Linux_并发_进程相关函数

创建子进程 函数声明如下&#xff1a; pid_t fork(void); 返回值&#xff1a;失败返回-1&#xff0c;成功返回两次&#xff0c;子进程获得0(系统分配)&#xff0c;父进程获得子进程的pid 注意&#xff1a;fork创建子进程&#xff0c;实际上就是将父进程复制一遍作为子进程&…

傅里叶级数在机器人中的应用(动力学参数辨识)

B站首发&#xff01;草履虫都能看懂的【傅里叶变换】讲解&#xff0c;清华大学李永乐老师教你如何理解傅里叶变换&#xff0c;辨清美颜和变声原理&#xff0c;&#xff01;&#xff01;_哔哩哔哩_bilibiliB站首发&#xff01;草履虫都能看懂的【傅里叶变换】讲解&#xff0c;清…

Mac屏蔽系统更新,取出红点标记如果解锁hosts文件

引言&#xff1a;关闭系统更新&#xff0c;首先应该在系统偏好设置---软件更新---去掉自动更新的选项。即使如此&#xff0c;系统仍然进行macOS系统和自带safari等软件的检测更新&#xff0c;并图标右上角红点点标记提醒我们更新&#xff0c;那我们如果彻底屏蔽更新呢&#xff…

监控告警功能详细介绍及操作演示:运维团队的智能保障

在当今这个信息化高速发展的时代&#xff0c;运维团队面临着前所未有的挑战。为了确保系统的稳定性和高效运维&#xff0c;监控告警功能成为了运维团队不可或缺的得力助手。本文将详细介绍我们的监控告警功能&#xff0c;并结合实际操作页面进行演示&#xff0c;帮助运维团队更…

828华为云征文|部署在线文档应用程序 CodeX Docs

828华为云征文&#xff5c;部署在线文档应用程序 CodeX Docs 一、Flexus云服务器X实例介绍二、Flexus云服务器X实例配置2.1 重置密码2.2 服务器连接2.3 安全组配置2.4 Docker 环境搭建 三、Flexus云服务器X实例部署 CodeX Docs3.1 CodeX Docs 介绍3.2 CodeX Docs 部署3.3 CodeX…

AI产品经理PRD文档与传统产品经理PRD有什么不同呢?

目录 模型输出&#xff1a;说白了&#xff0c;就是你的AI要干啥数据接入&#xff1a;你的AI要吃啥“粮食”验收标准&#xff1a;怎么判断你的AI干得好不好经验总结 你好&#xff0c;我是三桥君 在工作中&#xff0c;当我作为传统产品经理时&#xff0c;通常只需提供产品需求文…

解决 Adobe 盗版弹窗

在这个文件夹下删除 Adobe CCXProcess 然后重装。 Adobe Premiere Pro 2024 (v24.6.1) Multilingual :: Варез от m0nkrusa [Warez by m0nkrus] (monkrus.ws) Adobe Photoshop 2024 (v25.12) Multilingual :: Варез от m0nkrusa [Warez by m0nkrus] (monkrus.…

Camera Raw:打开图像

在图像工作流程中&#xff0c;无论是 Raw 格式图像文件还是 JPEG、TIFF 文件&#xff0c;都可以先使用 Camera Raw 打开并调整后&#xff0c;再进入其它 Adobe 软件如 Photoshop 中进行进一步的编辑和处理。 一、打开 Raw 格式图像 1、通过 Adobe Bridge 打开 在 Adobe Bridge …

8.数据结构与算法-双向链表

双向链表的结构定义 从第二个指针找到下一个元素 从第一个指针找到上一个元素 双向循环列表 从第二个指针找到下一个元素&#xff0c;第二个指针可以往前循环找到链表开头 从第一个指针找到上一个元素&#xff0c;第一个指针可以往前循环昭侯链表结尾 双向链表的插入 双向链…

Australis 相機率定軟體說明

概要 課堂中使用Australis這套軟體&#xff0c;順帶記錄操作過程 內容以老師口述及我測試的經過 照片為老師課堂提供之 說明 執行 Step1. 匯入照片 注意&#xff01;&#xff01;如果是Mac的作業系統&#xff0c;將資料夾移到Windows上的時候&#xff0c;建議創一個新的資料…