Labelme转VOC格式

目录

1.VOC的数据内容

2.创建自己数据集


1.VOC的数据内容

VOC数据集的下载路径: The PASCAL Visual Object Classes Challenge 2012 (VOC2012)

打开链接后如下图所示,只用下载training/validation data (2GB tar file)文件即可。

VOCdevkit
    └── VOC2012
         ├── Annotations               所有的图像标注信息(XML文件)
         ├── ImageSets    
         │   ├── Action                人的行为动作图像信息
         │   ├── Layout                人的各个部位图像信息
         │   │
         │   ├── Main                  目标检测分类图像信息
         │   │     ├── train.txt       训练集(5717)
         │   │     ├── val.txt         验证集(5823)
         │   │     └── trainval.txt    训练集+验证集(11540)
         │   │
         │   └── Segmentation          目标分割图像信息
         │         ├── train.txt       训练集(1464)
         │         ├── val.txt         验证集(1449)
         │         └── trainval.txt    训练集+验证集(2913)
         │ 
         ├── JPEGImages                所有图像文件
         ├── SegmentationClass         语义分割png图(基于类别)
         └── SegmentationObject        实例分割png图(基于目标)

 注意,train.txtval.txttrainval.txt文件里记录的是对应图片的图片名,每一行对应一个图片名信息。我们需要关注的是ImageSets/ImageSets、JPEGImages、SegmentationClass这三个文件夹中的内容。

2.创建自己数据集

2.1 将数据在labelme中做标签,具体如何使用labelme转看另外一篇博客labelme使用教程,但是标注后只是josn格式的;

2.2 将josn格式的数据转为png格式的,采用labelme的github中转VOC的py文件josn转voc的py文件,生成JPEGImages、SegmentationClass文件。

#运行命令
#data_annotated是标注图像的名字,data_dataset_voc是新创建的VOC格式的文件名字。
python labelme2voc.py data_annotated data_dataset_voc --labels labels.txt

2.3 生成ImageSets/ImageSets文件。

代码如下:

import os
import random

import numpy as np
from PIL import Image
from tqdm import tqdm

#-------------------------------------------------------#
#   想要增加测试集修改trainval_percent 
#   修改train_percent用于改变验证集的比例 9:1
#   
#   当前该库将测试集当作验证集使用,不单独划分测试集
#-------------------------------------------------------#
trainval_percent    = 1
train_percent       = 0.9
#-------------------------------------------------------#
#   指向VOC数据集所在的文件夹
#   默认指向根目录下的VOC数据集
#-------------------------------------------------------#
VOCdevkit_path      = '/data/lifei/XinCode/compar code/dataset_VOC'

if __name__ == "__main__":
    random.seed(0)
    print("Generate txt in ImageSets.")
    segfilepath     = os.path.join(VOCdevkit_path, 'SegmentationClass')
    saveBasePath    = os.path.join(VOCdevkit_path, 'ImageSets/Segmentation')
    
    temp_seg = os.listdir(segfilepath)
    total_seg = []
    for seg in temp_seg:
        if seg.endswith(".png"):
            total_seg.append(seg)

    num     = len(total_seg)  
    list    = range(num)  
    tv      = int(num*trainval_percent)  
    tr      = int(tv*train_percent)  
    trainval= random.sample(list,tv)  
    train   = random.sample(trainval,tr)  
    
    print("train and val size",tv)
    print("traub suze",tr)
    ftrainval   = open(os.path.join(saveBasePath,'trainval.txt'), 'w')  
    ftest       = open(os.path.join(saveBasePath,'test.txt'), 'w')  
    ftrain      = open(os.path.join(saveBasePath,'train.txt'), 'w')  
    fval        = open(os.path.join(saveBasePath,'val.txt'), 'w')  
    
    for i in list:  
        name = total_seg[i][:-4]+'\n'  
        if i in trainval:  
            ftrainval.write(name)  
            if i in train:  
                ftrain.write(name)  
            else:  
                fval.write(name)  
        else:  
            ftest.write(name)  
    
    ftrainval.close()  
    ftrain.close()  
    fval.close()  
    ftest.close()
    print("Generate txt in ImageSets done.")

    print("Check datasets format, this may take a while.")
    print("检查数据集格式是否符合要求,这可能需要一段时间。")
    classes_nums        = np.zeros([256], np.int)
    for i in tqdm(list):
        name            = total_seg[i]
        png_file_name   = os.path.join(segfilepath, name)
        if not os.path.exists(png_file_name):
            raise ValueError("未检测到标签图片%s,请查看具体路径下文件是否存在以及后缀是否为png。"%(png_file_name))
        
        png             = np.array(Image.open(png_file_name), np.uint8)
        if len(np.shape(png)) > 2:
            print("标签图片%s的shape为%s,不属于灰度图或者八位彩图,请仔细检查数据集格式。"%(name, str(np.shape(png))))
            print("标签图片需要为灰度图或者八位彩图,标签的每个像素点的值就是这个像素点所属的种类。"%(name, str(np.shape(png))))

        classes_nums += np.bincount(np.reshape(png, [-1]), minlength=256)
            
    print("打印像素点的值与数量。")
    print('-' * 37)
    print("| %15s | %15s |"%("Key", "Value"))
    print('-' * 37)
    for i in range(256):
        if classes_nums[i] > 0:
            print("| %15s | %15s |"%(str(i), str(classes_nums[i])))
            print('-' * 37)
    
    if classes_nums[255] > 0 and classes_nums[0] > 0 and np.sum(classes_nums[1:255]) == 0:
        print("检测到标签中像素点的值仅包含0与255,数据格式有误。")
        print("二分类问题需要将标签修改为背景的像素点值为0,目标的像素点值为1。")
    elif classes_nums[0] > 0 and np.sum(classes_nums[1:]) == 0:
        print("检测到标签中仅仅包含背景像素点,数据格式有误,请仔细检查数据集格式。")

    print("JPEGImages中的图片应当为.jpg文件、SegmentationClass中的图片应当为.png文件。")
    print("如果格式有误,参考:")
    print("https://github.com/bubbliiiing/segmentation-format-fix")

可以根据自己的需求更改训练集以及验证集,修改对应的trainval_percent    = 1
train_percent       = 0.9代码即可;

修改为自己的数据路径VOCdevkit_path      = 'compar code/dataset_VOC'

修改为自己的SegmentationClass路径segfilepath     = os.path.join(VOCdevkit_path, 'SegmentationClass');

修改为自己的txt路径 saveBasePath    = os.path.join(VOCdevkit_path, 'ImageSets/Segmentation');

运行上边的代码即可,就可以将自己的数据划分为指定比例的TXT文件。

  • 3
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要将labelme标注的数据换为VOC格式,您可以按照以下步骤进行操作: 1. 安装labelme和lxml库: ``` pip install labelme lxml ``` 2. 将labelme标注的数据保存为JSON文件。 3. 创建一个Python脚本,将JSON文件换为VOC格式。以下是一个示例脚本: ```python import os import json from lxml import etree def labelme_to_voc(json_path, output_dir): with open(json_path, 'r') as f: data = json.load(f) # 创建VOC格式的XML文件 annotation = etree.Element("annotation") # 添加文件名 filename = etree.Element("filename") filename.text = os.path.basename(data['imagePath']) annotation.append(filename) # 添加图像大小 size = etree.Element("size") width = etree.Element("width") height = etree.Element("height") depth = etree.Element("depth") width.text = str(data['imageWidth']) height.text = str(data['imageHeight']) depth.text = "3" # 如果是RGB图像,设置为3,如果是灰度图像,设置为1 size.append(width) size.append(height) size.append(depth) annotation.append(size) # 添加目标信息 for shape in data['shapes']: obj = etree.Element("object") name = etree.Element("name") name.text = shape['label'] obj.append(name) polygon = etree.Element("polygon") for point in shape['points']: x, y = point point = etree.Element("point") point_x = etree.Element("x") point_x.text = str(x) point_y = etree.Element("y") point_y.text = str(y) point.append(point_x) point.append(point_y) polygon.append(point) obj.append(polygon) annotation.append(obj) xml_str = etree.tostring(annotation, pretty_print=True) xml_path = os.path.join(output_dir, os.path.splitext(os.path.basename(json_path))[0] + ".xml") with open(xml_path, 'wb') as xml_file: xml_file.write(xml_str) # 指定labelme标注数据的JSON文件路径 json_path = 'path/to/labelme.json' # 指定输出VOC格式的XML文件的目录 output_dir = 'path/to/output_dir' # 换为VOC格式 labelme_to_voc(json_path, output_dir) ``` 在上述示例脚本中,您需要替换`json_path`和`output_dir`为您的实际路径。运行脚本后,将会在指定的输出目录生成对应的VOC格式的XML文件。 请注意,此示例脚本假设labelme标注的数据中只包含一个目标,并且目标是多边形。如果您的数据有其他特殊情况,可能需要根据实际情况进行修改。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值