自动化迁移和更新物体检测XML数据集

引言

当处理大规模的图片数据集,尤其是在物体识别和计算机视觉领域时,有效管理和更新数据集变得非常重要。在本文中,我们将介绍一个简单的Python脚本,该脚本自动化了迁移和更新标注过的XML数据集的过程。

脚本概览

该脚本进行了以下操作:

  • 遍历给定目录下的所有XML注释文件。
  • 为每个注释文件创建对应的拷贝,并更新文件路径和名字。
  • 单独处理每个XML文件中的物体注释,保持标注信息不变。
  • 拷贝原图像文件到新的目录,并更新文件名。
  • 在终端输出处理进度,包括拷贝的图片和XML文件计数器。
  • 把独特的标签类别以及总计数保存到文本文件中。

使用场景

  • 更新数据集目录结构。
  • 从图片中提取注释信息,用于机器学习模型的训练。
  • 快速获取数据集的整体信息,包括包含了哪些类别。

代码解析

设置

在脚本的开始部分,我们首先导入必要的模块,并定义源目录和目标目录的路径。

import xml.etree.ElementTree as ET
from datetime import datetime
import os, cv2, time, shutil

这些模块包括操作XML文件的ElementTree,进行文件操作的os和shutil,还有处理图片的cv2等。

功能函数

脚本中定义了两个重要的函数来处理XML文件的创建和物体标记的添加。

def create_object(root, xi, yi, xa, ya, obj_name):# 创建物体标记代码# ...def create_tree(sources, image_name, h, w):# 创建XML文件树结构# ...

主循环

在主循环中,脚本读取每个注释文件,并对每个文件执行一系列操作:

for xml in annotation_list:# ... 每个文件的处理逻辑...

这包括通过OpenCV获取图片尺寸,使用shutil.copyfile拷贝图片文件,解析XML文件以读取和复制物体标注信息。

结果记录

脚本最后输出处理的总数,并将数据类别及其计数保存在文本文件中:

print(count)
labels_list = list(set(all_labels))
labels_len = len(labels_list)
labels_str = f"this datasets have {labels_len} classes, labels list is {labels_list}"
print(labels_str)
with open("record.txt", "w") as f:f.write(str(count))f.write("\n")f.write(labels_str)

结论

我们介绍的脚本可以帮助用户以一种简单高效的方式来处理和准备用于物体检测的图片数据集。通过使用此脚本,用户可以节省宝贵的时间并减少手动错误,提高了数据准备工作的效率。
代码
完整脚本可以在本文附带的代码段中找到。如果你有兴趣自己尝试或者修改以适应你的项目需求,欢迎下载和使用。

import xml.etree.ElementTree as ET
from datetime import datetime
import os, cv2, time, shutilinitial_dir_orin = "E:\\lindsay\\voc_dataset_kitchen"
now = datetime.now()
year = str(now.year)
month = str(now.month).zfill(2)
day = str(now.day).zfill(2)
time_path = year+month+day
initial_dir_orin_flag = time_path+"_"+str(time.time())
annotations_path = initial_dir_orin+"/annotations"
images_path = initial_dir_orin+"/images"new_images_path = time_path+"_repaire_datasets"+"/images"
new_annotations_path = time_path+"_repaire_datasets"+"/annotations"if not os.path.exists(new_images_path):os.makedirs(new_images_path)if not os.path.exists(new_annotations_path):os.makedirs(new_annotations_path)
all_labels = []
annotation_list = os.listdir(annotations_path)
print(len(annotation_list))
count = 0
# 定义一个创建一级分支object的函数
def create_object(root, xi, yi, xa, ya, obj_name):  # 参数依次,树根,xmin,ymin,xmax,ymax# 创建一级分支object_object = ET.SubElement(root, 'object')# 创建二级分支name = ET.SubElement(_object, 'name')# print(obj_name)name.text = str(obj_name)pose = ET.SubElement(_object, 'pose')pose.text = 'Unspecified'truncated = ET.SubElement(_object, 'truncated')truncated.text = '0'difficult = ET.SubElement(_object, 'difficult')difficult.text = '0'# 创建bndboxbndbox = ET.SubElement(_object, 'bndbox')xmin = ET.SubElement(bndbox, 'xmin')xmin.text = '%s' % xiymin = ET.SubElement(bndbox, 'ymin')ymin.text = '%s' % yixmax = ET.SubElement(bndbox, 'xmax')xmax.text = '%s' % xaymax = ET.SubElement(bndbox, 'ymax')ymax.text = '%s' % ya# 创建xml文件的函数
def create_tree(sources, image_name, h, w):imgdir = sources.split('/')[-1]# 创建树根annotationannotation = ET.Element('annotation')# 创建一级分支folderfolder = ET.SubElement(annotation, 'folder')# 添加folder标签内容folder.text = (imgdir)# 创建一级分支filenamefilename = ET.SubElement(annotation, 'filename')filename.text = image_name# 创建一级分支pathpath = ET.SubElement(annotation, 'path')path.text = '{}/{}'.format(sources, image_name)  # 用于返回当前工作目录# 创建一级分支sourcesource = ET.SubElement(annotation, 'source')# 创建source下的二级分支databasedatabase = ET.SubElement(source, 'database')database.text = 'Unknown'# 创建一级分支sizesize = ET.SubElement(annotation, 'size')# 创建size下的二级分支图像的宽、高及depthwidth = ET.SubElement(size, 'width')width.text = str(w)height = ET.SubElement(size, 'height')height.text = str(h)depth = ET.SubElement(size, 'depth')depth.text = '3'# 创建一级分支segmentedsegmented = ET.SubElement(annotation, 'segmented')segmented.text = '0'return annotationfor xml in annotation_list:count = count+1img = xml.split(".xml")[0]image = os.path.join(images_path,img+".jpg")annotation = os.path.join(annotations_path,xml)img1 = cv2.imread(image)height, width, _ = img1.shapenew_image = os.path.join(new_images_path,initial_dir_orin_flag+"_"+str(count)+".jpg")new_annotation = os.path.join(new_annotations_path, initial_dir_orin_flag+"_"+str(count)+".xml")shutil.copyfile(image, new_image)annotation_create = create_tree(new_images_path,initial_dir_orin_flag+"_"+str(count)+".jpg", height, width)print(annotation)tree = ET.parse(annotation)root = tree.getroot()objects = root.findall('object')for i, obj in enumerate(objects):label = obj.find('name').textbb = obj.find('bndbox')x1 = int(bb.find('xmin').text)y1 = int(bb.find('ymin').text)x2 = int(bb.find('xmax').text)y2 = int(bb.find('ymax').text)print(x1, y1, x2, y2, label, end = '\t|\t')all_labels.append(label)create_object(annotation_create, x1, y1, x2, y2, label)tree = ET.ElementTree(annotation_create)tree.write(new_annotation)print("\n")
print(count)labels_list = list(set(all_labels))
labels_len = len(labels_list)
labels_str = f"this datasets have {labels_len} classes, labels list is {labels_list}"
print(labels_str)
with open("record.txt", "w") as f:f.write(str(count))f.write("\n")f.write(labels_str)

和任何自动化处理一样,使用这个脚本时,你应该先在少量文件上测试来确保它按预期执行,以避免意外的数据丢失或损坏。希望这个脚本和博客对你的项目有所帮助!

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

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

相关文章

vue3中多语言切换vue-i18n

安装 npm install vue-i18nnext 使用 一.在src中创建i18n文件夹(文件名无所谓) 在i18n下创建 en.ts zh.ts index.ts 分别写入下面代码 en.ts/js //en export default {message: {login: login} } zh.ts //zh export default {message: {login:…

Nginx网站服务【☆☆☆】

市面上常用Linux的web服务器:apache、Nginx。 apache与nginx的区别? 最核心的区别在于NGINX采用异步非阻塞机制,多个连接可以对应一个进程;apache采用的是同步阻塞多进程/线程模型,一个连接对应一个进程。apache美国…

MacOS 安装C语言版TensorFlow

文章目录 安装C语言版TensorFlow解压归档环境变量c_api.hC语言示例 安装C语言版TensorFlow 官方文档:https://tensorflow.google.cn/install/lang_c?hlzh-cnTensorFlow 提供了一个 C API,该 API 可用于为其他语言构建绑定。该 API 在 c_api.h 中定义&a…

从C到C++,C++入门(2)

在C入门篇(1)中,博主为大家简单介绍了什么是C,以及C中的关键字,命名空间,输入与输出和缺省参数的相关知识。今天就让我们继续一起学习C的基础知识点吧!! 1.函数重载 1.1函数重载的概…

经典的泡泡龙游戏源码免费下载

源码介绍 HTML5泡泡龙冒险小游戏是一款休闲网页游戏,游戏玩法是玩家从下方中央的弹珠发射台射出彩珠,多于3个同色珠相连则会消失。 源码下载 经典的泡泡龙游戏源码免费下载

C# WPF入门学习主线篇(六)—— TextBox常见属性和事件

欢迎回到C# WPF入门学习系列的第六篇。在前面的文章中,我们探讨了按钮(Button)的事件处理。今天,我们将继续学习另一个常用的WPF控件——TextBox。本文将介绍 TextBox 的常见属性和事件,并通过示例代码展示如何在实际应…

企业办公网安全管控挑战与解决方案

在数字化浪潮的推动下,企业正经历前所未有的变革。然而,随之而来的是一系列复杂的网络安全风险和挑战。我们的网络边界不再清晰,各种设备轻松接入企业网络,这不仅带来了便利,也极大地增加了安全风险。想象一下&#xf…

JavaScript 学习笔记 总结

回顾: Web页面标准 页面结构:HTML4、HTML5页面外观和布局:CSS页面行为:JavaScript强调三者的分离前后端分离开发模式 响应式设计Bootstrap框架入门 Bootstrap总结 基础 下载和使用基础样式:文本样式、图片样式、表格…

机器学习和深度学习相关指标和方法

什么是机器学习 机器学习是一门多学科交叉专业,它涵盖概率论、统计学、近似理论知识和复杂算法知识等领域。机器学习专门研究计算机如何模拟或实现人类的学习行为,以获取新的知识或技能,并重新组织已有的知识结构,从而不断改善自…

Vue Router 使用教程

Vue Router 是 Vue.js 的官方路由管理器,它提供了一种方便的方式来管理应用的路由。在本教程中,我们将介绍 Vue Router 的一些常见用法和示例。 一、安装 Vue Router 使用 Vue Router 之前,需要先安装它。可以使用以下命令通过 npm 安装&am…

笔记 | 软件工程03:软件过程和软件开发方法

软件过程 1 何为软件过程模型 1.1 软件开发的特点 1.2 软件过程 1.3 软件过程模型 1.3.1 软件过程模型产生的背景 软件工程产生之前的软件开发——作坊式的个人创作:聚焦于编写代码;依靠个体技能,缺乏合作;关注时空利用&#x…

SWIG源码安装

SWIG源码安装 https://github.com/swig 下载源码首先需要先生成.configure,在执行make & make install ./autogen.sh test -d Tools/configaclocal -I Tools/config ./autogen.sh: 11: aclocal: not found报错了 解决方案,安装automake sudo ap…

Threejs加载DOM+CSS到场景中,实现3D场景展示2D平面的效果

1. 前言 本篇文章主要实现了将DOM元素转换为Threejs可以使用的数据结构,使用CSS2DRenderer渲染器渲染这些DOMCSS的平面,使其可以作为一个物体添加到Threejs场景里 如下效果图: 2. 实现步骤 首先创建一个ThreejsVueVite的项目,作为本次的demo项目下载Threejs第三方库 yarn…

C++候捷stl-视频笔记4

一个万用的hash function 哈希函数的形式,一种是一般函数(右边),一种是成员函数(左边),类的对象将成为函数对象 具体做法例子。直接把属性的所有hash值加起来,会在hashtable中会产生很多的碰撞,放在同一个bucket中的元…

游戏UI设计秘诀:专家总结与实际案例解析!

随着游戏产业的不断发展,游戏UI界面设计变得越来越重要。一个好的游戏UI界面设计可以让玩家更容易理解游戏规则,提高游戏的可玩性,增加游戏的吸引力。在本文中,我们将讨论游戏UI界面设计的重要性和一些常见的设计原则。 1. 游戏U…

为什么要选择AWS?AWS的优势有哪些?

在当今时代,云计算已经成为各行各业的必备技术。作为全球领先的云计算平台,AWS(Amazon Web Services)凭借其卓越的性能、可靠性和创新能力,吸引了无数企业和个人开发者选择使用其服务。但是,为什么要选择AWS呢?AWS又有哪些独特的优势呢?让我们结合九河云的分析一起探讨一下。…

前端框架中的虚拟DOM和实际DOM之间的关系

聚沙成塔每天进步一点点 本文回顾 ⭐ 专栏简介前端框架中的虚拟DOM和实际DOM之间的关系1. 实际DOM(Real DOM)1.1 定义1.2 特点 2. 虚拟DOM(Virtual DOM)2.1 定义2.2 特点 3. 虚拟DOM的工作流程3.1 创建虚拟DOM3.2 比较虚拟DOM&…

Django redirect()函数实现页面重定向

1,通过路由反向解析进行重定向 1.1 添加视图函数 myshop/app2/views.py from django.http import HttpResponse from django.shortcuts import render from django.urls import reverse def index(request):return HttpResponse("app2 的index")# 反向…

PVE安装虚拟主机

本文记录PVE安装其他虚拟主机的步骤,以安装win-server为例。裸机安装PVE则不是本文主题。 准备文件 获取Windows系统镜像 win server镜像可以从官网获取普通Windows镜像可从MSDN获取此外,安装Windows系统还需要从PVE下载特殊驱动 获取Windows必要驱动 …

康谋技术 | 自动驾驶:揭秘高精度时间同步技术(二)

在自动驾驶中,对车辆外界环境进行感知需要用到很多传感器的数据(Lidar,Camera,GPS/IMU),如果计算中心接收到的各传感器消息时间不统一,则会造成例如障碍物识别不准等问题。 为了对各类传感器进…