目标检测实例分割数据集转换:从XML和JSON到YOLOv8(txt)

yolov8导航

        如果大家想要了解关于yolov8的其他任务和相关内容可以点击这个链接,我这边整理了许多其他任务的说明博文,后续也会持续更新,包括yolov8模型优化、sam等等的相关内容。

YOLOv8(附带各种任务详细说明链接)

源码下载地址:

XML&JSON 目标检测、实例分割标签转换给yolo用脚本

引言

        在计算机视觉领域,目标检测是一个重要而复杂的任务。随着深度学习技术的发展,各种高效的算法和模型如YOLOv8不断涌现。然而,在使用这些先进模型之前,必须确保我们的数据集是正确格式化的。今天,我将分享一段Python代码,它能够将XML和JSON格式的标注文件转换为适合YOLOv8模型训练的格式。

数据集转换的重要性

        在目标检测任务中,我们通常有两种常见的标注格式:XML和JSON。而YOLOv8需要的是一种特定格式的文本文件,其中包含了目标的类别和位置信息。因此,将现有的标注文件转换为YOLO格式是实施有效训练的第一步。

源码

        这段代码大体包含两个功能,可以转换xml、json格式的目标检测以及实例分割任务的标签,填写的时候需要根据要求填写标签所在的路径:

import json
import pandas as pd
import xml.etree.ElementTree as ET
import os, cv2
import numpy as np
import globclasses = []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 - 1w = box[1] - box[0]h = box[3] - box[2]x = x * dww = w * dwy = y * dhh = h * dhreturn (x, y, w, h)def convert_annotation(xmlpath, xmlname):with open(xmlpath, "r", encoding='utf-8') as in_file:txtname = xmlname[:-4] + '.txt'txtfile = os.path.join(txtpath, txtname)tree = ET.parse(in_file)root = tree.getroot()filename = root.find('filename')img = cv2.imdecode(np.fromfile('{}/{}.{}'.format(imgpath, xmlname[:-4], postfix), np.uint8), cv2.IMREAD_COLOR)h, w = img.shape[:2]res = []for obj in root.iter('object'):cls = obj.find('name').textif cls not in classes:classes.append(cls)cls_id = classes.index(cls)xmlbox = obj.find('bndbox')b = (float(xmlbox.find('xmin').text), float(xmlbox.find('xmax').text), float(xmlbox.find('ymin').text),float(xmlbox.find('ymax').text))bb = convert((w, h), b)res.append(str(cls_id) + " " + " ".join([str(a) for a in bb]))if len(res) != 0:with open(txtfile, 'w+') as f:f.write('\n'.join(res))def query_json_to_txt(dir_json, dir_txt):classes2id = {}num = 0jsons = os.listdir(dir_json)for i in jsons:json_path = os.path.join(dir_json, i)with open(json_path, 'r', encoding="utf-8") as f:json_data = json.load(f)# print(json_data['shapes'])for j in json_data['shapes']:if j['label'] not in classes2id:classes2id[j['label']] = numnum += 1def json2txt(path_json, path_txt):  # 可修改生成格式with open(path_json, 'r', encoding='utf-8') as path_json:jsonx = json.load(path_json)with open(path_txt, 'w+') as ftxt:shapes = jsonx['shapes']# 获取图片长和宽width = jsonx['imageWidth']height = jsonx['imageHeight']# print(shapes)cat = shapes[0]['label']cat = classes2id[cat]for shape in shapes:# 获取矩形框两个角点坐标x1 = shape['points'][0][0]y1 = shape['points'][0][1]x2 = shape['points'][1][0]y2 = shape['points'][1][1]dw = 1. / widthdh = 1. / heightx = dw * (x1 + x2) / 2y = dh * (y1 + y2) / 2w = dw * abs(x2 - x1)h = dh * abs(y2 - y1)yolo = f"{cat} {x} {y} {w} {h} \n"ftxt.writelines(yolo)list_json = os.listdir(dir_json)for cnt, json_name in enumerate(list_json):if os.path.splitext(json_name)[-1] == ".json":path_json = dir_json + json_namepath_txt = dir_txt + json_name.replace('.json', '.txt')json2txt(path_json, path_txt)pd.DataFrame([{"原始类别": k, "编码": v} for k,v in classes2id.items()]).to_excel("label_codes.xlsx", index=None)###################### 实例分割处理 #######################################
def parse_json_for_instance_segmentation(json_path, label_dict={}):# 打开并读取JSON文件with open(json_path, 'r', encoding='utf-8') as file:json_info = json.load(file)annotations = []  # 初始化一个用于存储注释的列表# 遍历JSON文件中的每个形状(shape)for shape in json_info["shapes"]:label = shape["label"]  # 获取实例分割类别的标签# 如果标签在标签字典中 则直接编码if label in label_dict:label_dict[label] = label_dict[label]  # 为该标签分配一个编码# 如果不在标签中else:next_label_code = max(label_dict.values(), default=-1) + 1label_dict[label] = next_label_codecat = label_dict[label]  # 获取该标签对应的编码points = shape["points"]  # 获取形状的点# 将点转换为字符串格式,并按照图像的宽度和高度进行归一化points_str = ' '.join([f"{round(point[0]/json_info['imageWidth'], 6)} {round(point[1]/json_info['imageHeight'], 6)}" for point in points])annotation_str = f"{cat} {points_str}\n"  # 将编码和点字符串合并为一行注释annotations.append(annotation_str)  # 将该注释添加到列表中return annotations, label_dict  # 返回注释列表和更新后的标签字典def process_directory_for_instance_segmentation(json_dir, txt_save_dir, label_dict=None):if not os.path.exists(txt_save_dir):os.makedirs(txt_save_dir)# 如果没有提供初始的label_dict,则从空字典开始final_label_dict = label_dict.copy() if label_dict is not None else {}json_files = [f for f in os.listdir(json_dir) if f.endswith(".json")]for json_file in json_files:json_path = os.path.join(json_dir, json_file)txt_path = os.path.join(txt_save_dir, json_file.replace(".json", ".txt"))# 每次解析时传递当前的final_label_dictannotations, updated_label_dict = parse_json_for_instance_segmentation(json_path, final_label_dict)# 更新final_label_dict,确保包括所有新标签及其编码final_label_dict.update(updated_label_dict)# 检查annotations是否为空,如果为空则跳过写入操作if annotations:with open(txt_path, "w") as file:file.writelines(annotations)# 保存最终的标签字典pd.DataFrame(list(final_label_dict.items()), columns=['原始Label', '编码后Label']).to_excel('label_codes.xlsx', index=False)return final_label_dict# 传入参数为 实例分割 和 目标检测
query_type = "目标检测"
# 传入原始标签数据,比如xml、json格式文件所在的目录下
label_directory = './query_data/xy/Annotations/'
# 填写想转换的txt输出到哪里
output_directory = './query_data/xy/txt/'anno_files = glob.glob(label_directory + "*")
file_type = anno_files[0].split(".")[-1]label_dict = {# 如果想预设标签就在这里填入对应的键值对
}if query_type == "实例分割":process_directory_for_instance_segmentation(label_directory, output_directory, label_dict)elif query_type == "目标检测":if file_type == "json":query_json_to_txt(label_directory, output_directory)## 处理xml格式文件elif file_type == "xml" or file_type == "XML":postfix = 'jpg'imgpath = 'query_data/xy/images'xmlpath = 'query_data/xy/Annotations'txtpath = 'query_data/xy/txt'if not os.path.exists(txtpath):os.makedirs(txtpath, exist_ok=True)file_list = glob.glob(xmlpath + "/*")error_file_list = []for i in range(0, len(file_list)):try:path = file_list[i]if ('.xml' in path) or ('.XML' in path):convert_annotation(path, path.split("\\")[-1])print(f'file {list[i]} convert success.')else:print(f'file {list[i]} is not xml format.')except Exception as e:print(f'file {list[i]} convert error.')print(f'error message:\n{e}')error_file_list.append(list[i])print(f'this file convert failure\n{error_file_list}')print(f'Dataset Classes:{classes}')

脚本功能解析

处理XML文件

        XML格式广泛用于多种图像标注工具中。我们的脚本首先解析XML文件,提取出其中的目标类别和边界框信息。然后,这些信息被转换为YOLO格式,并保存在相应的.txt文件中。

处理JSON文件

        JSON格式也是一种常见的标注格式,尤其在实例分割任务中。脚本中包含的函数query_json_to_txt能够处理这些JSON文件,将它们转换为YOLO格式,并生成一个包含类别名称和编号的映射表。

实例分割数据处理

        对于实例分割任务,我们的脚本还提供了解析JSON文件的功能,提取出多边形的坐标信息,并转换为YOLO格式。

使用指南

要使用此脚本,您只需按照如下步骤操作:

  1. 确定您的数据集类型(目标检测或实例分割)。
  2. 准备您的XML或JSON标注文件。
  3. 运行脚本进行转换。
  4. 使用生成的文本文件训练您的YOLOv8模型。

结语

        数据预处理是机器学习项目中至关重要的一步。通过本文介绍的脚本,您可以轻松地将XML和JSON格式的标注文件转换为适合YOLOv8模型的格式。这不仅节省了大量时间,也为实现高效的目标检测任务奠定了基础。如果有哪里写的不够清晰,小伙伴本可以给评论或者留言,我这边会尽快的优化博文内容,另外如有需要,我这边可支持技术答疑与支持。

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

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

相关文章

2023-12-12LeetCode每日一题(下一个更大元素 IV)

2023-12-12每日一题 一、题目编号 2454. 下一个更大元素 IV二、题目链接 点击跳转到题目位置 三、题目描述 给你一个下标从 0 开始的非负整数数组 nums 。对于 nums 中每一个整数,你必须找到对应元素的 第二大 整数。 如果 nums[j] 满足以下条件,那…

「网络编程」其他重要的协议或技术_ DNS协议 | ICMP协议 | NAT技术

「前言」文章内容是DNS协议、ICMP协议、NAT技术的讲解。 「归属专栏」网络编程 「主页链接」个人主页 「笔者」枫叶先生(fy) 目录 一、DNS协议1.1 背景1.2 域名简介1.3 域名解析的过程 二、ICMP协议2.1 ICMP简介2.2 ping命令2.3 traceroute命令 三、NAT技术3.1 NAT技术背景3.2 …

【算法提升—力扣每日一刷】五日总结【12/25--12/29】

文章目录 LeetCode每五日一总结【12/25--12/29】2023/12/25今日数据结构:双锁实现阻塞队列 2023/12/26每日力扣:[215. 数组中的第K个最大元素(堆实现)](https://leetcode.cn/problems/kth-largest-element-in-an-array/) 2023/12/…

uniapp中的uview组件库丰富的Form 表单用法

目录 基本使用 #Form-item组件说明 #验证规则 #验证规则属性 #uView自带验证规则 #综合实战 #校验错误提示方式 #校验 基本使用 此组件一般是用于表单验证使用,每一个表单域由一个u-form-item组成,表单域中可以放置u-input、u-checkbox、u-radio…

typescript 类装饰器的执行顺序

分类: class 类装饰器method 方法装饰器gettersetterfield 属性装饰器accessor 存取器装饰器 装饰器的执行分为两个阶段。 (1)评估(evaluation):计算符号后面的表达式的值,得到的应该是函数。…

伺服电机:原点复位

一、原点复位概念 原点复位指的是,在驱动器使能时,触发原点复位功能后,电机将主动查找零点,完成定位功能。 那么问题来了,什么是原点,什么是零点? 原点:即机械原点,可…

人机对话:2024年有什么新机遇?

人机对话:2024年有什么新机遇? 2024年有什么新机遇?对于这个问题,我咨询了几个人工智能平台,得出一些不同的结果。 INSCODE AI 创作助手 2024年有许多新的机遇可以追逐。以下列出了一些可能的新机遇: 科…

四、Mysql数据库编程[触发器、存储过程、函数]

一、数据库编程 1.触发器 解释:触发器(trigger)能够在sql里面自动执行,当设定好某个条件,当条件满足时,sql将自动执行某些语句 ,其中触发器里面有关键字NEW和OLD代表修改前和修改后的值 -- 创…

基于JAVA的独居老人物资配送系统 开源项目

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块三、系统展示四、核心代码4.1 查询社区4.2 新增物资4.3 查询物资4.4 查询物资配送4.5 新增物资配送 五、免责说明 一、摘要 1.1 项目介绍 基于JAVAVueSpringBootMySQL的独居老人物资配送系统,包含了社区档案、…

【sql】_![CDATA[]]_和转义字符:

文章目录 一、转义字符二、<![CDATA[]]>三、<![CDATA[]]>和xml转移字符的关系&#xff0c;它们两个看起来是不是感觉功能重复了&#xff1f; 所有 XML 文档中的文本均会被解析器解析。 只有 CDATA 区段&#xff08;CDATA section&#xff09;中的文本会被解析器忽略…

RK3399平台入门到精通系列讲解(导读篇)21天挑战Linux系统开发

🚀返回总目录 文章目录 一、关于作者1、博主的联系方式2、支持二、需要具备的知识和工具1、需掌握知识点2、需了解的知识点三、通过系列博客可以学到什么1、本系列博文特色2、21天学习目标3、21天学习内容4、学习时间5、学习产出

操作系统——文件系统

分区 C盘、D盘等都是同一块硬盘上的不同分区。每个分区被操作系统视为独立的逻辑磁盘&#xff0c;它们可以有不同的文件系统、格式以及分配的存储空间。 卷 拥有文件系统的分区就叫做卷。 挂载&#xff08;mount&#xff09; 建立操作系统的逻辑地址和物理介质的物理地址之…

【解决问题】pyinstaller打包python应用进行快速分发

pyinstaller打包python应用进行快速分发 问题起因先利其器再善其事试用运行 问题起因 有同学问我要接口的应用&#xff0c;于是试了一下python打包成exe的过程。 先利其器 主要使用pyinstaller&#xff0c;可以通过pip安装 pip install pyinstaller安装过程如图 再善其事…

B+树的插入删除

操作 插入 case2的原理,非叶子节点永远和最右边的最左边的节点的值相等。 case3:的基本原理 非叶子节点都是索引节点 底层的数据分裂之后 相当于向上方插入一个新的索引(你可以认为非叶子节点都是索引),反正第二层插入160 都要分裂,然后也需要再插入(因为索引部分不需要重…

2023-12-27 LeetCode每日一题(保龄球游戏的获胜者)

2023-12-27每日一题 一、题目编号 2660. 保龄球游戏的获胜者二、题目链接 点击跳转到题目位置 三、题目描述 给你两个下标从 0 开始的整数数组 player1 和 player2 &#xff0c;分别表示玩家 1 和玩家 2 击中的瓶数。 保龄球比赛由 n 轮组成&#xff0c;每轮的瓶数恰好为…

数据分析工具 Top 8

你能想象一个没有工具箱的水管工吗? 没有,对吧? 数据从业者也是如此。如果没有他们的数据分析工具&#xff0c;数据从业者就无法分析数据、可视化数据、从数据中提取价值&#xff0c;也无法做数据从业者在日常工作中做的许多很酷的事情。 根据你最感兴趣的数据科学职业——数…

前后台分离开发

前后台分离开发 简介 前后台分离开发&#xff0c;就是在项目开发过程中&#xff0c;对于前端代码的开发由专门的前端开发人员负责&#xff0c;后端代码则由后端开发人员负责&#xff0c;这样可以做到分工明确、各司其职&#xff0c;提高开发效率&#xff0c;前后端代码并行开…

SpringBoot 日志打印

一. 自定义打印日志 开发者自定义打印日志实现步骤: • 在程序中得到日志对象 • 使用日志对象的相关语法输出要打印的内容. 得到日志对象: //日志工厂需要将需要打印的类的类型传递进去,这样我们才知道日志的归属类,才能更方便的定位到文体类 private static Logger logger …

深入理解Session与Cookie:Java Web应用中的状态管理

在Web应用中&#xff0c;状态管理是一个核心概念&#xff0c;它涉及到如何在用户的多次请求之间保持和传递信息。HTTP协议本身是无状态的&#xff0c;意味着服务器并不默认记住之前的请求。为了解决这个问题&#xff0c;开发人员使用了两种主要的技术&#xff1a;Session和Cook…

2023年12月记录内容管理

文章目录 前言1.[vue构建项目](https://mp.csdn.net/mp_blog/creation/editor/134829688)2. [Nodejs后端+express框架](https://mp.csdn.net/mp_blog/creation/editor/134841711)3. [前端知识点](https://mp.csdn.net/mp_blog/creation/editor/132810879)4.[前端知识点-vue篇(…