将VOC2012目标检测数据集xml标注转化为yolov3可供训练txt文件代码分享

话不多说,先上代码

import os
import xml.etree.cElementTree as ET

class_code = {"person": 0, "bird": 1, "cat": 2, "cow": 3, "dog": 4, "horse": 5, "sheep": 6, "aeroplane": 7,
              "bicycle": 8, "boat": 9, "bus": 10, "car": 11, "motorbike": 12, "train": 13, "bottle": 14,
              "chair": 15, "diningtable": 16, "pottedplant": 17, "sofa": 18, "tvmonitor": 19}

"""
将VOC2012的xml标注文件转化为txt形式的标注文件,内容为图片名称、物体种类、中心点坐标、box宽高:
[图片名称 物体1的class_code 物体1中心点x 物体1中心点y 物体1box宽度 物体1box高度 物体2的class_code......]

类初始化时,参数为官方下载VOC2012数据解压后VOC2012文件夹地址
类实例化对象调用时,参数为:
1.存放txt目标文件夹地址 
2.mode===>str类型:
"train":只转化VOC2012数据集下目标检测数据集的train集
"val":只转化VOC2012数据集下目标检测数据集的val集
"trainval":只转化VOC2012数据集下目标检测数据集的trainval集(train与val并集)
"all":转化VOC2012数据集下目标检测数据集,包括train、val、trainval各集
"""


class GetobjectdetectiondatafromVoc2012():
    def __init__(self, base_root):
        self.baseroot = base_root

    def findobjectdetectiondatafromvoc2012(self):                    # 在VOC2012找到目标检测相关dataset划分并分类返回
        allobjtxtlsit = []
        obj_traintxtfile = os.path.join(self.baseroot, "ImageSets", "Main", "train.txt")
        obj_valtxtfile = os.path.join(self.baseroot, "ImageSets", "Main", "val.txt")
        obj_trainvaltxtfile = os.path.join(self.baseroot, "ImageSets", "Main", "trainval.txt")
        allobjtxtlsit.append(obj_traintxtfile)
        allobjtxtlsit.append(obj_valtxtfile)
        allobjtxtlsit.append(obj_trainvaltxtfile)
        # print(allobjtxtlsit)

        datanames = {}
        for txtfilename in allobjtxtlsit:
            with open(txtfilename, "r") as f:
                txtfiledirname = os.path.basename(txtfilename)
                datanames[txtfiledirname] = f.readlines()

        return datanames["train.txt"], datanames["val.txt"], datanames["trainval.txt"]

    def __call__(self, target_dir, mode):
        if os.path.exists(target_dir):                                     # 存放新txt目标文件夹检测,若没有则创建
            print("lables数据文件夹已存在:{}".format(target_dir))
        else:
            os.mkdir(target_dir)
            print("lables数据文件夹已创立:{}".format(target_dir))
        traindatanameslist, valdatanameslist, trainvaldatanameslist = self.findobjectdetectiondatafromvoc2012()

        target_dataset = []
        if mode == "train":
            target_dataset.append(traindatanameslist)
        elif mode == "val":
            target_dataset.append(valdatanameslist)
        elif mode == "trainval":
            target_dataset.append(trainvaldatanameslist)
        elif mode == "all":
            target_dataset.append(traindatanameslist)
            target_dataset.append(valdatanameslist)
            target_dataset.append(trainvaldatanameslist)

        order = ["train", "val", "trainval"]
        txtfilename_index = 0
        for mission in target_dataset:
            picnum = 0
            boxnum = 0

            if mode == "all":
                txtfilename = order[txtfilename_index]
            else:
                txtfilename = mode

            for datanames in mission:
                lable = []

                lable.append(datanames[:-1] + ".jpg")
                xml_file = os.path.join(self.baseroot, "Annotations", datanames[:-1] + ".xml")
                tree = ET.parse(xml_file)
                try:
                    for obj in tree.iter("object"):
                        lable.append(class_code[obj.findtext("name")])

                        xmin = int(obj.findtext("bndbox/xmin"))
                        ymin = int(obj.findtext("bndbox/ymin"))
                        xmax = int(obj.findtext("bndbox/xmax"))
                        ymax = int(obj.findtext("bndbox/ymax"))

                        cx = (xmin + xmax) / 2
                        cy = (ymin + ymax) / 2
                        w = xmax - xmin
                        h = ymax - ymin
                        lable.append(str(cx))
                        lable.append(str(cy))
                        lable.append(str(w))
                        lable.append(str(h))

                        boxnum += 1

                except:
                    print(lable[0])

                with open(os.path.join(target_dir, txtfilename + "_annotations.txt"), "a+") as f:
                    lable = [str(e) + " " for e in lable]
                    lable.append("\n")
                    f.writelines(lable)

                picnum += 1
            print("{}_labes.txt成功共转化{}张图片的标签,共计{}个物体框".format(txtfilename, picnum, boxnum))
            txtfilename_index += 1


if __name__ == '__main__':
    database_root = r"G:\AI data\VOCdevkit\VOC2012"          # VOC2012数据文件夹地址
    target_root = r"G:\Coding\yolov3\data\label_txt"         # 存放txt文件地址
    labletxtgentor = GetobjectdetectiondatafromVoc2012(database_root)
    labletxtgentor(target_root, "all")

官方下载VOC2012数据后,VOC2012官方数据包下载解压后如图:

无需其他任何操作,简单调整参数后直接跑代码,结果:

 此代码文章仅供免费学习使用,请勿用于个人商用,如果你觉得有用,请点个赞,谢谢。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值