labelme转YOLOv8、YOLOv5 标签格式 标注数据

news2024/11/15 13:49:50

前言

本文分析将labelme的标签,转为YOLOv8、YOLOv5的格式,实现模型训练。

首先了解YOLOv8和YOLOv5标签格式,然后了解labelme标签格式,最近实现数据格式转换。

1、YOLOv8和YOLOv5标签格式

YOLOv8 的标签格式与 YOLOv5 基本相同,使用一种简单的txt文本格式,来存储每个图像的标注数据。

  • 每个图像对应一个文本文件,这些文本文件与图像文件位于同一目录
  • 并且具有相同的文件名,但标签文件类型是 .txt

每个文本文件包含多行,每一行代表一个物体的标注。每行包含以下信息:(相邻数据用空格间隔开)

<class_id> <x_center> <y_center> <width> <height>

  • <class_id>: 类别 ID,从 0 开始。
  • <x_center>: 边界框中心的 x 坐标,归一化到图像宽度(值在 0 到 1 之间)。
  • <y_center>: 边界框中心的 y 坐标,归一化到图像高度(值在 0 到 1 之间)。
  • <width>: 边界框的宽度,归一化到图像宽度(值在 0 到 1 之间)。
  • <height>: 边界框的高度,归一化到图像高度(值在 0 到 1 之间)。

示例:假设有一张名为 image01.jpg 的图像,其对应的标签文件 image01.txt 包含以下内容:

0 0.5 0.5 0.25 0.25
1 0.3 0.3 0.1 0.2

这表示图像中有两个对象:

  • 第一个对象的类别 ID 是 0,边界框中心点在图像的中间 (0.5, 0.5),边界框的宽度和高度分别是图像宽度和高度的 25%。
  • 第二个对象的类别 ID 是 1,边界框中心点在图像的左上方 (0.3, 0.3),边界框的宽度是图像宽度的 10%,高度是图像高度的 20%。

2、labelme标签格式

开源地址:https://github.com/labelmeai/labelme

Labelme 是一个图像标注工具,通常用于生成用于训练机器学习模型的标注数据。

Labelme 输出的数据格式是 JSON 文件,其中包含图像的标注信息。

{
    "version": "4.2.10",
    "flags": {},
    "shapes": [
        {
            "label": "class1",
            "points": [
                [x1, y1],
                [x2, y2],
                ...
            ],
            "group_id": null,
            "shape_type": "polygon",
            "flags": {}
        },
        {
            "label": "class2",
            "points": [
                [x1, y1],
                [x2, y2],
                ...
            ],
            "group_id": null,
            "shape_type": "rectangle",
            "flags": {}
        }
    ],
    "imagePath": "image_name.jpg",
    "imageData": "base64_encoded_image_data",
    "imageHeight": 1024,
    "imageWidth": 768
}
  • version: Labelme 软件的版本号。
  • flags: 一个可选的标志字典,通常为空。
  • shapes: 一个列表,包含每个标注的详细信息。
    • label: 这个标注的标签名称。
    • points: 一个数组,包含标注的点的坐标。对于多边形,每个点用 (x, y) 表示;对于矩形,通常有两个点:左上角和右下角。
    • group_id: 一个可选的组 ID,用于标记同一组的多个形状。
    • shape_type: 形状的类型,例如 "polygon"、"rectangle"、"circle" 等。
    • flags: 可选的标志字典,通常为空。
  • imagePath: 原始图像的路径或名称。
  • imageData: 图像数据的 base64 编码字符串。这个字段可以为空,如果有图像路径信息的话。
  • imageHeight: 图像的高度。
  • imageWidth: 图像的宽度。

3、labelme转YOLOv8、YOLOv5

首先定义标签名字和数字的映射 ,比如有两个类别car、bus。

label_map = {
    "car": 0,
    "bus": 1
}

如果只有单个类别,比如car。

label_map = {
    "car": 0
}

方案1——单个文件转换,代码如下所示:

import json
import os

# 定义标签映射
label_map = {
    "car": 0,
    "bus": 1
}

def convert_labelme_to_yolo(json_path, output_dir):
    with open(json_path, 'r') as f:
        labelme_data = json.load(f)

    image_width = labelme_data['imageWidth']
    image_height = labelme_data['imageHeight']

    yolo_annotations = []
    for shape in labelme_data['shapes']:
        label = shape['label']
        if label not in label_map:
            continue  # 忽略未定义的标签

        class_id = label_map[label]

        points = shape['points']
        if shape['shape_type'] == 'rectangle':
            (x1, y1), (x2, y2) = points
        elif shape['shape_type'] == 'polygon':
            x1, y1 = min(point[0] for point in points), min(point[1] for point in points)
            x2, y2 = max(point[0] for point in points), max(point[1] for point in points)
        else:
            continue  # 其他类型不处理

        x_center = (x1 + x2) / 2.0 / image_width
        y_center = (y1 + y2) / 2.0 / image_height
        width = (x2 - x1) / image_width
        height = (y2 - y1) / image_height

        yolo_annotations.append(f"{class_id} {x_center} {y_center} {width} {height}")

    output_file = os.path.join(output_dir, os.path.splitext(os.path.basename(json_path))[0] + '.txt')
    with open(output_file, 'w') as f:
        f.write('\n'.join(yolo_annotations))

# 示例使用
convert_labelme_to_yolo('/path/to/labelme_file.json', '/path/to/output_dir')

方案2——多个标签文件转换

读取一个文件下所有json文件,然后转为YOLO的txt标签格式

import json
import os

# 定义标签映射
label_map = {
    "car": 0,
    "bus": 1
}

def convert_labelme_to_yolo(json_path, output_dir):
    with open(json_path, 'r') as f:
        labelme_data = json.load(f)

    image_width = labelme_data['imageWidth']
    image_height = labelme_data['imageHeight']

    yolo_annotations = []
    for shape in labelme_data['shapes']:
        label = shape['label']
        if label not in label_map:
            continue  # 忽略未定义的标签

        class_id = label_map[label]

        points = shape['points']
        if shape['shape_type'] == 'rectangle':
            (x1, y1), (x2, y2) = points
        elif shape['shape_type'] == 'polygon':
            x1, y1 = min(point[0] for point in points), min(point[1] for point in points)
            x2, y2 = max(point[0] for point in points), max(point[1] for point in points)
        else:
            continue  # 其他类型不处理

        x_center = (x1 + x2) / 2.0 / image_width
        y_center = (y1 + y2) / 2.0 / image_height
        width = (x2 - x1) / image_width
        height = (y2 - y1) / image_height

        yolo_annotations.append(f"{class_id} {x_center} {y_center} {width} {height}")

    output_file = os.path.join(output_dir, os.path.splitext(os.path.basename(json_path))[0] + '.txt')
    with open(output_file, 'w') as f:
        f.write('\n'.join(yolo_annotations))

def process_folder(input_folder, output_folder):
    # 创建输出文件夹(如果不存在)
    os.makedirs(output_folder, exist_ok=True)
    
    # 处理输入文件夹中的每个 JSON 文件
    for filename in os.listdir(input_folder):
        if filename.endswith(".json"):
            json_path = os.path.join(input_folder, filename)
            convert_labelme_to_yolo(json_path, output_folder)

# 示例使用
input_folder = "/mnt/data/buffer_nails_all"
output_folder = "/mnt/data/yolo_labels"

process_folder(input_folder, output_folder)

# 列出输出文件夹中的文件以确认
os.listdir(output_folder)

分享完成~

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

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

相关文章

拿到一个职称,竟然有这么多好处,你不知道吗?

很多从事建筑行业的小伙伴们都想评一个职称&#xff0c;但是很多人可能都是跟风&#xff0c;觉得同事评一个我也要评一个&#xff0c;那么拿到职称具体有哪些好处&#xff1f;甘建二给您分享一下&#xff1a; 1.专业认可&#xff1a; 俗话说&#xff0c;术业有专攻&#xff0c…

电磁兼容(EMC):整改案例(一)无时钟电路哪来的窄带干扰

目录 1. 异常现象 2. 原因分析 3. 整改方案 4. 总结 1. 异常现象 某家电用电器产品依据GB 4343.1-2018 家用电器、电动工具和类似器具的电磁兼容要求 第1部分&#xff1a;发射进行端子电压测试&#xff0c;测试结果如下图示。在频点40MHz裕量不足&#xff0c;仅有0.4dB。 2…

【因果推断python】28_面板数据和固定效应2

目录 固定效应 固定效应 为了方面后面更正式地讲述&#xff0c;让我们首先看一下我们拥有的数据。按照我们的例子&#xff0c;我们将尝试估计婚姻对收入的影响。我们的数据包含多年以来多个个体 (nr) 的这两个变量&#xff0c;married 和lwage。请注意&#xff0c;工资采用对数…

无线麦克风什么牌子的音质效果好?轻揭无线领夹麦克风哪个牌子好

​随着科技的不断发展&#xff0c;无线领夹麦克风已经成为现代演讲、演出和采访中不可或缺的工具。这种小巧便携的设备&#xff0c;能够让我们摆脱线缆的束缚&#xff0c;自由地在舞台上或讲台上移动&#xff0c;同时保持声音的清晰和稳定。在这篇文章中&#xff0c;我们将介绍…

【课程总结】Day6(下):机器学习项目实战–成人收入预测

机器学习项目实战&#xff1a;成人收入预测 项目目的 基于个人收入数据(包括教育程度、年龄、性别等)的数据集&#xff0c;通过机器学习算法&#xff0c;预测一个人的年收入是否超过5万美金。 数据集 地址&#xff1a;http://idatascience.cn/dataset-detail?table_id10036…

【UML用户指南】-14-对高级结构建模-实例

目录 1、实例的组成结构 1.1、类型 1.2、名称 1.3、操作 1.4、状态 1.5、其他特征 1.5.1、主动对象 1.5.2、链 1.5.3、静态属性 1.6、标准元素 实例是抽象的具体表现&#xff0c;可以对它施加一组操作&#xff0c;而且它可能有一组状态&#xff0c;来存储操作的结果。…

leetcode-04-[24]两两交换链表中的节点[19]删除链表的倒数第N个节点[160]相交链表[142]环形链表II

一、[24]两两交换链表中的节点 重点&#xff1a;暂存节点 class Solution {public ListNode swapPairs(ListNode head) {ListNode dummyHeadnew ListNode(-1);dummyHead.nexthead;ListNode predummyHead;//重点&#xff1a;存节点while(pre.next!null&&pre.next.next…

AI智能体的分级

技术的分级 人们往往通过对一个复杂的技术进行分级&#xff0c;明确性能、适用范围和价值&#xff0c;方便比较、选择和管理&#xff0c;提高使用效率&#xff0c;促进资源合理分配和技术改进和标准化。 比如&#xff0c;国际汽车工程师学会&#xff08;SAE&#xff09;定义了自…

CANOpen转PROFINET网关连接低压伺服系统

在现代工业自动化领域&#xff0c;随着技术的不断进步&#xff0c;各种总线通讯协议之间的转换和互操作性变得越来越重要。CANOpen和PROFINET作为两种广泛应用的通讯协议&#xff0c;各自具有独特的优势和应用场景。然而&#xff0c;在实际应用中&#xff0c;往往需要将CANOpen…

python使用wkhtmltopdf将html字符串保存pdf,解决出现方框的问题

出现的问题: 解决办法: <html> <head><meta charset="UTF-8"/> </head> <style> * {font-family: Arial,SimSun !important; } </style> </html>在html字符串前面加上上面代码,意思是设置字体编码和样式 html示例:…

vue2前置路由守卫中使用this.$store.state报错解决

1、问题描述&#xff1a;在前置路由守卫逻辑中&#xff0c;要更改vuex中的store的state状态&#xff0c;使用常规的this.$store.state报错 2、问题原因&#xff1a; 在vue2是vueRouter前置路由守卫中&#xff0c;this关键字并不会指向vue实例&#xff0c;因此不能使用this.$st…

如何优雅的实现Excel导入通用处理流程

目录 1.业务背景2.业务导入流程3.流程优化3.1 模板模式3.1.1 导入处理器接口ImportProcessor3.1.2 抽象父类 AbstractImportProcessor3.1.3 子类实现 ImportDemoProcessor 3.2 工厂模式3.2.1 标识子类的枚举ImportTypeEnum3.2.2 工厂类ProcessorHolder3.2.3 工厂类的调用 4. 特…

纹理贴图必须要输入顶点坐标或纹理坐标吗

最近知识星球的一位同学,面试时被问到:纹理贴图必须要输入顶点坐标或纹理坐标吗? 他一下子被这个问题问蒙了,虽然他知道正确答案是否定的,但是说不上来理由。 这个就引出了文本提到的全屏三角形,它不需要顶点缓冲区,而是利用顶点着色器直接生成所需的顶点坐标和纹理坐标…

【CTS】android CTS测试

android CTS测试 1.硬件准备2. 软件准备3. 下载 CTS3.1 cts3.2 解压 CTS 包&#xff1a; 4 配置adb fastboot5 检查 Java 版本6 安装aapt26.1 下载并安装 Android SDK6.2 找到 aapt2 工具6.3 配置环境变量 7. 准备测试设备8. 运行 CTS 测试8.1 启动 CTS&#xff1a; 9. 查看测试…

DDD架构和微服务初步实现

本次记录的是微服务的初步认识和DDD架构的初步实现和思路&#xff0c;在之前的发布里&#xff0c;对Javaweb进行了一次小总结&#xff0c;还有一些东西&#xff0c;不去详细理解说明了&#xff0c;下面开始我对微服务的理解。 什么是微服务&#xff1f; 在刚刚开始学习的时候…

【让AI写高考AI话题作文】看各大模型的回答

文章目录 命题chatGPT问题的消失&#xff0c;思考的萎缩 通义千问标题&#xff1a;在信息洪流中寻找智慧之光 文心一言探寻未知&#xff0c;拥抱无限的问题 命题 阅读下面的材料&#xff0c;根据要求写作。&#xff08;60分&#xff09; 随着互联网的普及、人工智能的应用&am…

快速锁定Bug!掌握Wireshark等抓包技术,提升测试效率

前言 相信做了测试一段时间的小伙伴都会开始意识到抓包对于测试的重要性&#xff0c;它涉及到功能测试、性能测试、自动化测试、安全测试和数据库测试等等。可以说我们要想做好测试就必须和抓包打交道&#xff0c;脱离抓包的测试是不合格的。人们都说黑客利用Wireshark等抓包工…

未来校园的新质生产力:南京江北新区浦口外国语学校校园网升级改造的启示

作者:南京江北新区浦口外国语学校 校长助理 杨美玲 导语:在南京江北新区(第十三个国家级新区),浦口外国语学校,这所拥有77605平方米宽阔校园、169个班级、7335名学生和511位专任教师的九年一贯制公办外语特色学校,正以前所未有的活力和智慧,迎接信息化时代的挑战。作为学校信息…

【JMeter接口测试工具】第二节.JMeter基本功能介绍(下)【进阶篇】

文章目录 前言八、Jmeter常用逻辑控制器 8.1 如果&#xff08;if&#xff09;控制器 8.2 循环控制器 8.3 ForEach控制器九、Jmeter关联 9.1 正则表达式提取器 9.2 xpath提取器 9.3 JSON提取器十、跨越线程组传值 10.1 高并发 10.2 高频…

1996-2023年各省农林牧渔总产值数据(无缺失)

1996-2023年各省农林牧渔总产值数据&#xff08;无缺失&#xff09; 1、 时间&#xff1a;1996-2023年 2、 来源&#xff1a;国家统计局、统计年鉴 3、 指标&#xff1a;农林牧渔总产值 4、 范围&#xff1a;31省 5、 缺失情况&#xff1a;无缺失 6、 指标解释&…