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

批量清洗与修改 YOLO 标签:删除与替换指定类别


在使用 YOLO 格式的数据进行训练或部署前,常常需要对标签文件进行清洗或修改。本文整理了两种常见场景的 Python 脚本:删除指定类别修改某类为其他类,并支持自动打印检测到该类别的文件名,帮助你快速定位问题数据。


📁 标签格式说明(YOLO格式)

YOLO 标签通常为 .txt 文件,每行格式如下:

<类别ID> <x_center> <y_center> <width> <height>

场景一:删除类别为 10 的标注,并输出相关文件名

该脚本会扫描指定目录下的所有 .txt 标签文件,删除类别为 10 的标注行,并在发现该类别时输出文件名。

import osdef process_txt_file(file_path):with open(file_path, 'r') as file:lines = file.readlines()# 检查是否存在以 "10" 开头的行has_class_10 = any(line.strip().startswith("10") for line in lines)# 过滤掉以 "10" 开头的行filtered_lines = [line for line in lines if not line.strip().startswith("10")]# 输出含有类别10的文件名if has_class_10:print(f"⚠️ 检测到类别10: {file_path}")# 重新写入过滤后的内容with open(file_path, 'w') as file:file.writelines(filtered_lines)def process_folder(folder_path):for root, dirs, files in os.walk(folder_path):for file in files:if file.endswith(".txt"):file_path = os.path.join(root, file)process_txt_file(file_path)# 修改为你自己的标签路径
folder_to_process = "/path/to/labels"
process_folder(folder_to_process)

场景二:将类别 11 修改为 10

有时我们需要将错误标注的类别进行更正,例如将所有类别为 11 的改为 10。

import osdef modify_yolo_labels(directory, old_class=11, new_class=10):for filename in os.listdir(directory):if filename.endswith(".txt"):file_path = os.path.join(directory, filename)with open(file_path, 'r') as f:lines = f.readlines()new_lines = []modified = Falsefor line in lines:parts = line.strip().split()if len(parts) > 0 and parts[0] == str(old_class):parts[0] = str(new_class)modified = Truenew_lines.append(' '.join(parts) + '\n')if modified:print(f"修改类别11为10:{file_path}")with open(file_path, 'w') as f:f.writelines(new_lines)# 替换为你的目录
label_folder = "/path/to/labels"
modify_yolo_labels(label_folder)

以下是将“删除类别”和“替换类别”功能封装为一个 YOLO 标签清洗工具类 的完整实现,便于项目中调用或集成到数据清洗流程中。 yolo_label_cleaner.py 模块:


import osclass YOLOLabelCleaner:def __init__(self, folder_path):self.folder_path = folder_pathdef delete_class(self, target_class):"""删除所有标签文件中类别为 target_class 的标注行,并输出涉及文件名。"""print(f"\n🧹 删除类别:{target_class}")for root, _, files in os.walk(self.folder_path):for file in files:if file.endswith('.txt'):file_path = os.path.join(root, file)with open(file_path, 'r') as f:lines = f.readlines()has_target = any(line.strip().startswith(str(target_class)) for line in lines)filtered = [line for line in lines if not line.strip().startswith(str(target_class))]if has_target:print(f" 检测到类别{target_class}: {file_path}")with open(file_path, 'w') as f:f.writelines(filtered)def replace_class(self, old_class, new_class):"""替换所有标签文件中 old_class 为 new_class,并输出修改的文件名。"""print(f"\n 替换类别:{old_class}{new_class}")for root, _, files in os.walk(self.folder_path):for file in files:if file.endswith('.txt'):file_path = os.path.join(root, file)with open(file_path, 'r') as f:lines = f.readlines()new_lines = []modified = Falsefor line in lines:parts = line.strip().split()if len(parts) > 0 and parts[0] == str(old_class):parts[0] = str(new_class)modified = Truenew_lines.append(' '.join(parts) + '\n')if modified:print(f"修改类别{old_class}{new_class}: {file_path}")with open(file_path, 'w') as f:f.writelines(new_lines)

使用示例

from yolo_label_cleaner import YOLOLabelCleaner# 指定标签路径
label_dir = "/mnt/data/code/szl/dataset/self-driving/SelfDriving/test/labels"
cleaner = YOLOLabelCleaner(label_dir)# 删除类别10
cleaner.delete_class(10)# 替换类别11为10
cleaner.replace_class(11, 10)

如果需要替换多类别,可以进行下面的修改:

import osclass YOLOLabelCleaner:def __init__(self, folder_path):self.folder_path = folder_pathdef delete_class(self, target_class):print(f"\n 删除类别:{target_class}")for root, _, files in os.walk(self.folder_path):for file in files:if file.endswith('.txt'):file_path = os.path.join(root, file)with open(file_path, 'r') as f:lines = f.readlines()has_target = any(line.strip().startswith(str(target_class)) for line in lines)filtered = [line for line in lines if not line.strip().startswith(str(target_class))]if has_target:print(f"检测到类别{target_class}: {file_path}")with open(file_path, 'w') as f:f.writelines(filtered)def replace_class(self, old_class, new_class):print(f"\n替换类别:{old_class}{new_class}")self.replace_classes_bulk({old_class: new_class})def replace_classes_bulk(self, class_map: dict):"""批量替换多个类别,class_map 格式为 {old_class: new_class}"""print(f"\n批量替换类别: {class_map}")for root, _, files in os.walk(self.folder_path):for file in files:if file.endswith('.txt'):file_path = os.path.join(root, file)with open(file_path, 'r') as f:lines = f.readlines()modified = Falsenew_lines = []for line in lines:parts = line.strip().split()if parts and int(parts[0]) in class_map:old = parts[0]parts[0] = str(class_map[int(old)])modified = Truenew_lines.append(' '.join(parts) + '\n')if modified:print(f"✅ 替换成功: {file_path}")with open(file_path, 'w') as f:f.writelines(new_lines)

使用示例(批量替换)

from yolo_label_cleaner import YOLOLabelCleaner# 初始化
label_dir = "/test/labels"
cleaner = YOLOLabelCleaner(label_dir)# 替换多个类别:11 ➜ 10, 12 ➜ 9, 13 ➜ 8
class_map = {11: 10,12: 9,13: 8
}
cleaner.replace_classes_bulk(class_map)

相关文章:

批量清洗与修改 YOLO 标签:删除与替换指定类别

在使用 YOLO 格式的数据进行训练或部署前&#xff0c;常常需要对标签文件进行清洗或修改。本文整理了两种常见场景的 Python 脚本&#xff1a;删除指定类别 和 修改某类为其他类&#xff0c;并支持自动打印检测到该类别的文件名&#xff0c;帮助你快速定位问题数据。 &#x1f…...

Python项目源码57:数据格式转换工具1.0(csv+json+excel+sqlite3)

1.智能路径处理&#xff1a;自动识别并修正文件扩展名&#xff0c;根据转换类型自动建议目标路径&#xff0c;实时路径格式验证&#xff0c;自动补全缺失的文件扩展名。 2.增强型预览功能&#xff1a;使用pandastable库实现表格预览&#xff0c;第三方模块自己安装一下&#x…...

TypeScript 中,属性修饰符

在 TypeScript 中&#xff0c;属性修饰符&#xff08;Property Modifiers&#xff09;是用于修饰类的属性或方法的关键字&#xff0c;它们可以改变属性或方法的行为和访问权限。TypeScript 提供了三种主要的属性修饰符&#xff1a;public、private 和 protected。此外&#xff…...

雷赛伺服电机

ACM0经济 编码器17位&#xff1a; ACM1基本 编码器23位磁编&#xff0c; ACM2通用 编码器24位光电&#xff0c; 插头定义&#xff1a;...

基础编程题目集 6-8 简单阶乘计算

本题要求实现一个计算非负整数阶乘的简单函数。 函数接口定义&#xff1a; int Factorial( const int N ); 其中N是用户传入的参数&#xff0c;其值不超过12。如果N是非负整数&#xff0c;则该函数必须返回N的阶乘&#xff0c;否则返回0。 裁判测试程序样例&#xff1a; #in…...

【deepseek教学应用】001:deepseek如何撰写教案并自动实现word排版

本文讲述利用deepseek如何撰写教案并自动实现word高效完美排版。 文章目录 一、访问deepseek官网二、输入教案关键词三、格式转换四、word进一步排版 一、访问deepseek官网 官网&#xff1a;https://www.deepseek.com/ 进入主页后&#xff0c;点击【开始对话】&#xff0c;如…...

CH32V208GBU6沁恒绑定配对获取静态地址

从事嵌入式单片机的工作算是符合我个人兴趣爱好的,当面对一个新的芯片我即想把芯片尽快搞懂完成项目赚钱,也想着能够把自己遇到的坑和注意事项记录下来,即方便自己后面查阅也可以分享给大家,这是一种冲动,但是这个或许并不是原厂希望的,尽管这样有可能会牺牲一些时间也有哪天原…...

【C/C++】RPC与线程间通信:高效设计的关键选择

文章目录 RPC与线程间通信&#xff1a;高效设计的关键选择1 RPC 的核心用途2 线程间通信的常规方法3 RPC 用于线程间通信的潜在意义4 主要缺点与限制4.1 缺点列表4.2 展开 5 替代方案6 结论 RPC与线程间通信&#xff1a;高效设计的关键选择 在C或分布式系统设计中&#xff0c;…...

跨线程和跨进程通信还有多种方式对比

📊 常见通信机制对比 通信方式跨线程支持跨进程支持同步/异步性能编程复杂度特点与适用场景SendMessage✅✅(同桌面)同步较高(阻塞)低简单窗口通信、控制PostMessage✅✅(同桌面)异步高低通知、事件触发COM/DCOM✅✅同步/异步中中高系统级服务、进程间服务封装Socket✅…...

RT Thread Studio创建软件和硬件RTC工程

MCU型号&#xff1a;STM32F103RET6 一.配置软件模拟RTC 1.生成一个带串口输出的工程文件&#xff0c;新建RT-Thread项目工程文件。 2.查看电路图中的串口输出管脚&#xff0c;根据STMCubeMx软件可知此串口为USART1&#xff0c;选择芯片型号为STM32F103RET6&#xff0c;控制台…...

Oracle EBS AP发票被预付款核算创建会计科目时间超长

背景 由于客户职能部门的水电、通信和物业等等费用统一管理或对接部门报销费,在报销费的时候,用户把所有费用分摊到各个末级部门,形成AP发票行有上千行, 问题症状 1、用户过账时,请求创建会计科目一直执行20多个小时未完成,只能手工强行取消请求。 2、取消请求以后,从后…...

驱动开发硬核特训 · Day 30(下篇): 深入解析 lm48100q I2C 音频编解码器驱动模型(基于 i.MX8MP)

作者&#xff1a;嵌入式Jerry 视频教程请关注 B 站&#xff1a;“嵌入式Jerry” 一、背景与目标 在本篇中&#xff0c;我们围绕 TI 的 lm48100q 音频编解码器 展开&#xff0c;深入讲解其作为 I2C 外设如何集成至 Linux 内核音频子系统&#xff08;ASoC&#xff09;&#xff0…...

运维--计划任务

计划任务分为一次性和循环性的计划任务 1.date的用法 date 月日时分年 eg:date 100118222023 date:查看时间和日期、修改时间和日期 获取当前日期:date +%F F:日期 获取当前时间:date +%H:%M:%S H:时 M:分 S:秒 获取周几: date +%w w:周 …...

苍穹外卖心得体会

1 登录认证 技术点&#xff1a;JWT令牌技术&#xff08;JSON Web Token&#xff09; JWT&#xff08;JSON Web Token&#xff09;是一种令牌技术&#xff0c;主要由三部分组成&#xff1a;Header头部、Payload载荷和Signature签名。Header头部存储令牌的类型&#xff08;如JW…...

Python爬虫实战:获取jd商城最新5060ti 16g显卡销量排行榜商品数据并做分析,为显卡选购做参考

一、引言 1.1 研究目的 本研究旨在利用 Python 爬虫技术,从京东商城获取 “5060ti 16g” 型号显卡的商品数据,并对这些数据进行深入分析。具体目标包括: 实现京东商城的模拟登录,突破登录验证机制,获取登录后的访问权限。高效稳定地爬取按销量排名前 20 的 “5060ti 16g…...

Fedora升级Google Chrome出现GPG check FAILED问题解决办法

https://dl.google.com/linux/linux_signing_key.pub 的 GPG 公钥(0x7FAC5991)已安装 https://dl.google.com/linux/linux_signing_key.pub 的 GPG 公钥(0xD38B4796)已安装 仓库 "google-chrome" 的 GPG 公钥已安装&#xff0c;但是不适用于此软件包。 请检查此仓库的…...

信息系统监理师第二版教材模拟题第三组(含解析)

信息系统监理师模拟题第三组(30题) 监理基础理论 信息系统工程监理的性质是( ) A. 服务性、独立性、公正性、科学性 B. 强制性、营利性、行政性、技术性 C. 临时性、从属性、随意性、主观性 D. 单一性、封闭性、被动性、保守性答案:A 解析:监理具有服务性、独立性、公正…...

Zcanpro搭配USBCANFD-200U在新能源汽车研发测试中的应用指南(周立功/致远电子)

——国产工具链的崛起与智能汽车测试新范式 引言&#xff1a;新能源汽车测试的国产化突围 随着新能源汽车智能化、网联化程度的提升&#xff0c;研发测试面临三大核心挑战&#xff1a;多协议融合&#xff08;CAN FD/LIN/以太网&#xff09;、高实时性数据交互需求、复杂工况下…...

青少年抑郁症患者亚群结构和功能连接耦合的重构

目录 1 研究背景及目的 2 研究方法 2.1 数据来源与参与者 2.1.1 MDD患者&#xff1a; 2.1.2 健康对照组&#xff1a; 2.2 神经影像分析流程 2.2.1 图像采集与预处理&#xff1a; 2.2.2 网络构建&#xff1a; 2.2.3 区域结构-功能耦合&#xff08;SC-FC耦合&#xff09…...

SQL手工注入(DVWA)

手工SQL注入攻击的标准思路 Low等级 &#xff08;1&#xff09;判断是否存在注入 &#xff08;2&#xff09;猜解字段个数 &#xff08;3&#xff09;确定字段顺序 &#xff08;4&#xff09;获取当前数据库 &#xff08;5&#xff09;获取当前数据库中的表 &#xff08…...

【大模型系列篇】Qwen3开源全新一代大语言模型来了,深入思考,更快行动

Qwen3开源模型全览 Qwen3是全球最强开源模型&#xff08;MoEDense&#xff09; Qwen3 采用混合专家&#xff08;MoE&#xff09;架构&#xff0c;总参数量 235B&#xff0c;激活仅需 22B。 Qwen3 预训练数据量达 36T&#xff0c;并在后训练阶段多轮强化学习&#xff0c;将非思…...

第 11 届蓝桥杯 C++ 青少组中 / 高级组省赛 2020 年真题,选择题详细解释

一、选择题 第 2 题 在二维数组按行优先存储的情况下&#xff0c;元素 a[i][j] 前的元素个数计算如下&#xff1a; 1. **前面的完整行**&#xff1a;共有 i 行&#xff0c;每行 n 个元素&#xff0c;总计 i * n 个元素。 2. **当前行的前面元素**&#xff1a;在行内&#x…...

flutter 专题 一百零四 Flutter环境搭建

Flutter简介 Flutter 是Google开发的一个移动跨平台&#xff08;Android 和 iOS&#xff09;的开发框架&#xff0c;使用的是 Dart 语言。和 React Native 不同的是&#xff0c;Flutter 框架并不是一个严格意义上的原生应用开发框架。Flutter 的目标是用来创建高性能、高稳定性…...

Android之Button、ImageButton、ChipGroup用法

一 控件名称及UI代码 Button、ImageButton、ChipGroup <?xml version="1.0" encoding="utf-8"?> <androidx.coordinatorlayout.widget.CoordinatorLayoutxmlns:android="http://schemas.android.com/apk/res/android"xmlns:app=&qu…...

【AI提示词】二八法则专家

提示说明 精通二八法则&#xff08;帕累托法则&#xff09;的广泛应用&#xff0c;擅长将其应用于商业、管理、个人发展等领域&#xff0c;深入理解其在不同场景中的具体表现和实际意义。 提示词 # Role: 二八法则专家## Profile - language: 中文 - description: 精通二八法…...

玩玩OCR

一、Tesseract: 1.下载windows版&#xff1a; tesseract 2. 安装并记下路径&#xff0c;等会要填 3.保存.py文件 import pytesseract from PIL import Image def ocr_local_image(image_path):try:pytesseract.pytesseract.tesseract_cmd rD:\Programs\Tesseract-OCR\tesse…...

set autotrace报错

报错&#xff1a; SQL> set autotrace traceonly SP2-0618: Cannot find the Session Identifier. Check PLUSTRACE role is enabled SP2-0611: Error enabling STATISTICS report原因分析&#xff1a; 根据上面的错误提示“SP2-0618: Cannot find the Session Identifie…...

C++如何设计和实现缓存(cache)来减少对后端存储的访问压力

随着数据量的激增和用户对低延迟、高吞吐量需求的不断提升,如何减少系统瓶颈、提升响应速度成为了开发者的核心挑战之一。在这一背景下,缓存(cache)作为一种关键的技术手段,逐渐成为解决性能问题的核心策略。缓存的本质是通过存储频繁访问的数据或计算结果,减少对后端存储…...

“Everything“工具 是 Windows 上文件名搜索引擎神奇

01 Everything 和其他搜索引擎有何不同 轻量安装文件。 干净简洁的用户界面。 快速文件索引。 快速搜索。 快速启动。 最小资源使用。 轻量数据库。 实时更新。 官网&#xff1a;https://www.voidtools.com/zh-cn/downloads/ 通过网盘分享的文件&#xff1a;Every…...

TIME_WAIT状态+UDP概念及模拟实现服务器和客户端收发数据

目录 一、TIME_WAIT状态存在的原因 二、TIME_WAIT状态存在的意义 三、TIME_WAIT状态的作用 四、UDP的基本概念 4.1 概念 4.2 特点 五、模拟实现UDP服务器和客户端收发数据 5.1 服务器udpser 5.2 客户端udpcil 一、TIME_WAIT状态存在的原因 1.可靠的终止TCP连接。 2.…...