最近使用yolo进行目标检测,但是手上的数据集既不是coco也不是voc,目前paddledetection上的网络只支持这两种格式。话不多说,直接进入正题:
1.首先了解voc数据集格式

└── VOCdevkit     #根目录
    └── VOC2017   
        ├── Annotations        #存放xml文件,与JPEGImages中的图片一一对应,解释图片的内容等等
        ├── ImageSets          
        │   ├── Action
        │   ├── Layout
        │   ├── Main├── train.txt#存放文件名
        │			├── val.txt
        │			└── test.txt
        │   └── Segmentation
        ├── JPEGImages         #存放源图片
        ├── label_list.txt#存放bbox标签
        ├── train.txt#JPEGImages图片路径与Annotations标签路径应
        ├── val.txt
        └── test.txt
        

查看我的数据格式,我的数据标签是json文件,下面给一张截图:
在这里插入图片描述
2.先从简单的开始
label_list.txt直接自己手写,看你的bbox有多少个类别,直接全写上就行,我的就两类,注意前面的序号1,2是notbook自带的,别写在这里插入图片描述·
3.第二步写train.txt,事实上共有两个train.txt文件,一个在ImageSets /Main/train.txt,另一个最直接在主目录下。下面直接贴代码:

import os
import json
import cv2
import random
 
# voc格式最后储存位置
voc_format_save_path = r'/home/aistudio/PaddleDetection/dataset/People/ImageSets/Main/train.txt'
# yolo格式的注释文件,上文有格式
yolo_format_annotation_path = r'/home/aistudio/PaddleDetection/dataset/peopledetection/train.json'
#另一个train保存路径
train_path = r'/home/aistudio/PaddleDetection/dataset/People/train.txt'

#判断文件是否存在,path为文件路径

if os.path.exists(voc_format_save_path):
    #删除文件,path为文件路径
    os.remove(voc_format_save_path)
if os.path.exists(train_path):
    #删除文件,path为文件路径
    os.remove(train_path)


# 前面都造好了基础(为了和coco一致,其实很多都用不到的),现在开始解析自己的数据
f = open(yolo_format_annotation_path,encoding='utf-8')
content = json.load(f)

file = open(voc_format_save_path,'a')
for j in range(len(content['annotations'])):
    img_path=content['annotations'][j]['name']
    img_name = os.path.basename(img_path)
    (img_name, extension) = os.path.splitext(img_name)
    img_name=img_name+'\n'
    file.write(img_name)
file.close()
print('保存成功1')

file2 = open(train_path,'a')
for j in range(len(content['annotations'])):
    img_path=content['annotations'][j]['name']
    img_name = os.path.basename(img_path)
    (img_name1, extension) = os.path.splitext(img_name)
    name='JPEGImages/'+str(img_name)+' '+'Annotations/'+str(img_name1)+'.xml\n'
    file2.write(name)
file2.close()
print('保存成功2')

最终保存的文件如下:
第一个train.txt,注意只有图片名,没有具体路径和后缀名
在这里插入图片描述
第二个train.txt,注意格式为:路径1+‘ ’+路径2\n
在这里插入图片描述
4.第三步生成.xml文件,贴代码:

import os, sys
import glob
from PIL import Image
import json
import cv2
import random
 
label_lists = []
img_lists = []
src_label_dir = '/home/aistudio/PaddleDetection/dataset/peopledetection/train.json'                           ###指向自己数据集的labelTxt文件夹
out_xml_dir = '/home/aistudio/PaddleDetection/dataset/People/Annotations/'  ###指向voc数据集的Annotations文件夹

f = open(src_label_dir,encoding='utf-8')
content = json.load(f)
for j in range(len(content['annotations'])):
    content['annotations'][j]['name'] = content['annotations'][j]['name'].lstrip('stage1').lstrip('/')
    img_path = content['annotations'][j]['name']
    img_name = os.path.basename(img_path)
    (img_name, extension) = os.path.splitext(img_name)
    # 因为需要width和height,而我得yolo文件里没有,所以我还得读图片,很烦
    # 我就用opencv读取了,当然用其他库也可以
    # 别把图片路径搞错了,绝对路径和相对路径分清楚!
    img_path = os.path.join('/home/aistudio/',img_path)
    height,width = cv2.imread(img_path).shape[:2]

    # write in xml file
    # os.mknod(src_xml_dir + '/' + img + '.xml')
    xml_file = open((out_xml_dir + '/' + img_name + '.xml'), 'w')
    xml_file.write('<annotation>\n')
    xml_file.write('    <folder>VOC2007</folder>\n')
    xml_file.write('    <filename>' + str(img_name) + '.jpg' + '</filename>\n')    ###若准备的图片为jpg格式则将png替换为jpg
    xml_file.write('    <path>' + str(img_path) + '.jpg' + '</path>\n')    ###若准备的图片为jpg格式则将png替换为jpg
    xml_file.write('    <size>\n')
    xml_file.write('        <width>' + str(width) + '</width>\n')
    xml_file.write('        <height>' + str(height) + '</height>\n')
    xml_file.write('        <depth>3</depth>\n')
    xml_file.write('    </size>\n')
    xml_file.write('    <segmented>0</segmented>\n')
    for bbox in  content['annotations'][j]['annotation']:
        xmin=bbox['x']
        ymin=bbox['y']
        xmax=bbox['x']+bbox['w']
        ymax=bbox['y']+bbox['h']
        gt_label = content['annotations'][j]['type']
        # 我就有时候int和str不注意各种报错
        xmin,ymin,xmax,ymax= int(xmin),int(ymin),int(xmax),int(ymax)
    

        xml_file.write('    <object>\n')
        xml_file.write('        <name>'+str(gt_label)+'</name>\n')
        xml_file.write('        <pose>Unspecified</pose>\n')
        xml_file.write('        <truncated>0</truncated>\n')
        xml_file.write('        <difficult>0</difficult>\n')
        xml_file.write('        <bndbox>\n')
        xml_file.write('            <xmin>'+str(xmin)+'</xmin>\n')
        xml_file.write('            <ymin>'+str(ymin)+'</ymin>\n')
        xml_file.write('            <xmax>'+str(xmax)+'</xmax>\n')
        xml_file.write('            <ymax>'+str(ymax)+'</ymax>\n')
        xml_file.write('        </bndbox>\n')
        xml_file.write('    </object>\n')
    xml_file.write('</annotation>')    
    xml_file.close()


生成的xml文件如下:
在这里插入图片描述
5.最后一步把图片文件copy到JPEGImages文件夹下,直接使用Linux命令

cp -r /home/aistudio/train/. /home/aistudio/PaddleDetection/dataset/People/JPEGImages

6.至此,所有的文件都搞定了,可以愉快地炼丹了,祝大家早日炼成金丹。
在这里插入图片描述
补充说明:验证集和测试集的操作和训练集操作一样,其他文件由于本实验没用到所以未作说明

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐