VOC格式数据集转yolo格式数据集的方法

现在开源的多数数据集都是VOC格式,但是往往我们使用的时候需要用到其它格式的数据集,愁的很,是不是需要重新一个一个的打标签呢?其实不用,只需要一段简单的代码就可以直接将VOC格式数据集转为yolo格式数据集,以下代码是可以直接自动分几个文件夹存放好训练集,验证集,以及对应对应标签的,数据集的分配比例也是可以自定义修改的。具体代码见下:

import xml.etree.ElementTree as ET
import pickle
import os
from os import listdir, getcwd
from os.path import join
import random
from shutil import copyfile

classes = ["Before a whole","After a whole","Chest former","Chest after","Raise hand before","Raise hand after","Global left position","Global right position","Front face","Left face","Right face"]        ##这里要写好标签对应的类
# classes=["ball"]

TRAIN_RATIO = 80     #表示将数据集划分为训练集和验证集,按照2:8比例来的


def clear_hidden_files(path):
    dir_list = os.listdir(path)
    for i in dir_list:
        abspath = os.path.join(os.path.abspath(path), i)
        if os.path.isfile(abspath):
            if i.startswith("._"):
                os.remove(abspath)
        else:
            clear_hidden_files(abspath)


def convert(size, box):
    dw = 1. / size[0]
    dh = 1. / size[1]
    x = (box[0] + box[1]) / 2.0
    y = (box[2] + box[3]) / 2.0
    w = box[1] - box[0]
    h = box[3] - box[2]
    x = x * dw
    w = w * dw
    y = y * dh
    h = h * dh
    return (x, y, w, h)


def convert_annotation(image_id):
    in_file = open('VOCdevkit/VOC2007/Annotations/%s.xml' % image_id)
    out_file = open('VOCdevkit/VOC2007/YOLOLabels/%s.txt' % image_id, 'w')
    tree = ET.parse(in_file)
    root = tree.getroot()
    size = root.find('size')
    w = int(size.find('width').text)
    h = int(size.find('height').text)

    for obj in root.iter('object'):
        difficult = obj.find('difficult').text
        cls = obj.find('name').text
        if cls not in classes or int(difficult) == 1:
            continue
        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)
        out_file.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n')
    in_file.close()
    out_file.close()


wd = os.getcwd()
wd = os.getcwd()
data_base_dir = os.path.join(wd, "VOCdevkit/")
if not os.path.isdir(data_base_dir):
    os.mkdir(data_base_dir)
work_sapce_dir = os.path.join(data_base_dir, "VOC2007/")
if not os.path.isdir(work_sapce_dir):
    os.mkdir(work_sapce_dir)
annotation_dir = os.path.join(work_sapce_dir, "Annotations/")
if not os.path.isdir(annotation_dir):
    os.mkdir(annotation_dir)
clear_hidden_files(annotation_dir)
image_dir = os.path.join(work_sapce_dir, "JPEGImages/")
if not os.path.isdir(image_dir):
    os.mkdir(image_dir)
clear_hidden_files(image_dir)
yolo_labels_dir = os.path.join(work_sapce_dir, "YOLOLabels/")
if not os.path.isdir(yolo_labels_dir):
    os.mkdir(yolo_labels_dir)
clear_hidden_files(yolo_labels_dir)
yolov5_images_dir = os.path.join(data_base_dir, "images/")
if not os.path.isdir(yolov5_images_dir):
    os.mkdir(yolov5_images_dir)
clear_hidden_files(yolov5_images_dir)
yolov5_labels_dir = os.path.join(data_base_dir, "labels/")
if not os.path.isdir(yolov5_labels_dir):
    os.mkdir(yolov5_labels_dir)
clear_hidden_files(yolov5_labels_dir)
yolov5_images_train_dir = os.path.join(yolov5_images_dir, "train/")
if not os.path.isdir(yolov5_images_train_dir):
    os.mkdir(yolov5_images_train_dir)
clear_hidden_files(yolov5_images_train_dir)
yolov5_images_test_dir = os.path.join(yolov5_images_dir, "val/")
if not os.path.isdir(yolov5_images_test_dir):
    os.mkdir(yolov5_images_test_dir)
clear_hidden_files(yolov5_images_test_dir)
yolov5_labels_train_dir = os.path.join(yolov5_labels_dir, "train/")
if not os.path.isdir(yolov5_labels_train_dir):
    os.mkdir(yolov5_labels_train_dir)
clear_hidden_files(yolov5_labels_train_dir)
yolov5_labels_test_dir = os.path.join(yolov5_labels_dir, "val/")
if not os.path.isdir(yolov5_labels_test_dir):
    os.mkdir(yolov5_labels_test_dir)
clear_hidden_files(yolov5_labels_test_dir)

train_file = open(os.path.join(wd, "yolov5_train.txt"), 'w')
test_file = open(os.path.join(wd, "yolov5_val.txt"), 'w')
train_file.close()
test_file.close()
train_file = open(os.path.join(wd, "yolov5_train.txt"), 'a')
test_file = open(os.path.join(wd, "yolov5_val.txt"), 'a')
list_imgs = os.listdir(image_dir)  # list image files
prob = random.randint(1, 100)
print("Probability: %d" % prob)
for i in range(0, len(list_imgs)):
    path = os.path.join(image_dir, list_imgs[i])
    if os.path.isfile(path):
        image_path = image_dir + list_imgs[i]
        voc_path = list_imgs[i]
        (nameWithoutExtention, extention) = os.path.splitext(os.path.basename(image_path))
        (voc_nameWithoutExtention, voc_extention) = os.path.splitext(os.path.basename(voc_path))
        annotation_name = nameWithoutExtention + '.xml'
        annotation_path = os.path.join(annotation_dir, annotation_name)
        label_name = nameWithoutExtention + '.txt'
        label_path = os.path.join(yolo_labels_dir, label_name)
    prob = random.randint(1, 100)
    print("Probability: %d" % prob)
    if (prob < TRAIN_RATIO):  # train dataset
        if os.path.exists(annotation_path):
            train_file.write(image_path + '\n')
            convert_annotation(nameWithoutExtention)  # convert label
            copyfile(image_path, yolov5_images_train_dir + voc_path)
            copyfile(label_path, yolov5_labels_train_dir + label_name)
    else:  # test dataset
        if os.path.exists(annotation_path):
            test_file.write(image_path + '\n')
            convert_annotation(nameWithoutExtention)  # convert label
            copyfile(image_path, yolov5_images_test_dir + voc_path)
            copyfile(label_path, yolov5_labels_test_dir + label_name)
train_file.close()
test_file.close()

关于文件之间的关系,可能有的学者有些迷惑,原始的VOC格式数据集文件该怎么存放,以及新生成的yolo格式数据集又会被存放到哪里,关于这些疑惑看下面讲解。

先复制VOC格式的数据集文件夹到上面代码所在的根目录下,见下:
在这里插入图片描述

在文件VOCdevkit中包含的内容见下:
在这里插入图片描述

运行上面的代码后就得到了新的yolo格式数据集,关于新数据集的文件关系见下:

在这里插入图片描述

上图中,我已经标明了哪个文件中存放训练用的数据集,验证集和哪个文件存放标签等的对应文件位置。

以上就是VOC格式数据集转yolo格式数据集的方法,希望能帮到和我一样正在掉头发的你,多多支持,谢谢!

  • 10
    点赞
  • 56
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 14
    评论
### 回答1: 将Java voc格式数据集换为Yolo(Darknet)格式,可以按照以下步骤进行操作: 1. 首先,需要了解VOC格式Yolo(Darknet)格式数据集结构和标注方式。 2. VOC格式通常包含一个XML文件夹,其中包含每个图像的XML文件和图像文件。每个XML文件中包含图像的宽度、高度以及在图像中的目标位置和类别信息。 3. 使用Java解析每个XML文件,提取出图像的宽度、高度和目标位置信息。 4. 将目标位置信息换为Yolo格式的位置信息。Yolo使用相对于图像宽度和高度的相对坐标来表示目标位置。需要使用以下公式将绝对坐标换为相对坐标: x_center = (xmin + xmax) / (2 * width) y_center = (ymin + ymax) / (2 * height) obj_width = (xmax - xmin) / width obj_height = (ymax - ymin) / height 其中,(xmin, ymin) 和 (xmax, ymax) 是目标框的左上角和右下角坐标,width 和 height 是图像的宽度和高度。 5. 根据目标类别信息,将Yolo格式的位置信息和类别信息写入Yolo格式的文本文件。Yolo格式的文本文件的每一行表示一个目标,并包含目标类别以及其在图像中的位置。 6. 重复步骤3-5,直到处理完所有的XML文件。 7. 最后,将换后的Yolo格式的文本文件和VOC格式的图像文件一起使用Yolo训练工具进行训练。 以上是将Java voc格式数据集换为Yolo(Darknet)格式的基本步骤。根据具体的实际需求,可能还需要进行一些额外的处理或修改。 ### 回答2: 要将Java voc格式数据集换为Yolo(Darknet)格式,可以按照以下步骤进行: 1. 确保你已经有了Java voc格式数据集,该数据集通常包含图像和相应的XML文件,每个XML文件中都包含有关图像中对象的位置和类别的信息。 2. 创建一个新的文件夹,用于存储换后的Yolo格式数据集。 3. 使用Java代码读取voc数据集中的XML文件,并解析其中的信息,获取对象的类别和边界框的位置。 4. 将解析得到的类别和边界框的信息换为Yolo格式的标注。Yolo格式的标注通常包含一个txt文件,每行表示一个对象的标注信息,包括类别的编号和边界框的归一化坐标(即左上角和右下角像素坐标除以图像宽度和高度)。 5. 将换后的Yolo格式的标注信息写入txt文件中,并将txt文件保存在新创建的文件夹中,与对应的图像文件放在同一目录下。 6. 重复步骤3至5,将所有图像的标注信息都换为Yolo格式的标注并保存。 7. 最后,将新创建的文件夹中的所有图像和标注文件复制到Darknet的数据集目录中,以便可以在训练或测试过程中使用。 通过以上步骤,你就可以将Java voc格式数据集成功换为Yolo(Darknet)格式数据集,以便用于目标检测任务。 ### 回答3: 将Java VOС格式数据集换为Yolo(darknet)格式,可以按照以下步骤进行操作: 1. 首先,了解Java VOC格式数据集。Java VOC(Visual Object Classes)是一种常用的图像数据集格式,用于物体检测任务。它由一个包含图像和标注信息的文件夹组成,标注信息通常为XML格式。 2. 确定Yolo(darknet)格式的要求。Yolo(darknet)是一种基于深度学习的物体检测框架,它要求数据集以特定的格式存储。Yolo(darknet)要求每个图像的标注信息存储在一个对应的txt文件中,每行包含一个目标的类别和边界框的坐标。 3. 开发一个Java程序来将Java VOC格式数据集换为Yolo(darknet)格式。可以使用Java的文件操作功能,按照以下步骤进行换: - 遍历Java VOC数据集的每个图像和对应的XML标注文件。 - 解析XML文件,提取目标的类别和边界框的坐标。 - 根据Yolo(darknet)格式的要求,将类别和边界框的坐标换为对应的格式,写入一个新的txt文件。 - 将新生成的txt文件与对应的图像放入Yolo(darknet)数据集文件夹中。 4. 运行该Java程序,并确保数据集中的所有图像都被成功换为Yolo(darknet)格式。可以逐个检查换后的txt文件,确保其格式正确且与图像对应。 通过以上步骤,您可以将Java VOC格式数据集换为Yolo(darknet)格式,以供Yolo(darknet)框架进行物体检测训练和测试。
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

视觉研坊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值