将VisDrone数据集转VOC格式 自己试了好使(气人 淘宝花钱转不理我 自己搞出来了 )

首先转个xml 是十二个类 是这个大佬的源码 注意改一下路径奥

# coding: utf-8
# author: HXY
# 2020-4-17

"""
该脚本用于visdrone数据处理;
将annatations文件夹中的txt标签文件转换为XML文件;
txt标签内容为:
,,,,,,,
类别:
ignored regions(0), pedestrian(1),
people(2), bicycle(3), car(4), van(5),
truck(6), tricycle(7), awning-tricycle(8),
bus(9), motor(10), others(11)
"""

import os
import cv2
import time
from xml.dom import minidom

name_dict = {'0': 'ignored regions', '1': 'pedestrian', '2': 'people',
             '3': 'bicycle', '4': 'car', '5': 'van', '6': 'truck',
             '7': 'tricycle', '8': 'awning-tricycle', '9': 'bus',
             '10': 'motor', '11': 'others'}


def transfer_to_xml(pic, txt, file_name):
    xml_save_path = 'xml'  # 生成的xml文件存储的文件夹
    if not os.path.exists(xml_save_path):
        os.mkdir(xml_save_path)

    img = cv2.imread(pic)
    img_w = img.shape[1]
    img_h = img.shape[0]
    img_d = img.shape[2]
    doc = minidom.Document()

    annotation = doc.createElement("annotation")
    doc.appendChild(annotation)
    folder = doc.createElement('folder')
    folder.appendChild(doc.createTextNode('visdrone'))
    annotation.appendChild(folder)

    filename = doc.createElement('filename')
    filename.appendChild(doc.createTextNode(file_name))
    annotation.appendChild(filename)

    source = doc.createElement('source')
    database = doc.createElement('database')
    database.appendChild(doc.createTextNode("Unknown"))
    source.appendChild(database)

    annotation.appendChild(source)

    size = doc.createElement('size')
    width = doc.createElement('width')
    width.appendChild(doc.createTextNode(str(img_w)))
    size.appendChild(width)
    height = doc.createElement('height')
    height.appendChild(doc.createTextNode(str(img_h)))
    size.appendChild(height)
    depth = doc.createElement('depth')
    depth.appendChild(doc.createTextNode(str(img_d)))
    size.appendChild(depth)
    annotation.appendChild(size)

    segmented = doc.createElement('segmented')
    segmented.appendChild(doc.createTextNode("0"))
    annotation.appendChild(segmented)

    with open(txt, 'r') as f:
        lines = [f.readlines()]
        for line in lines:
            for boxes in line:
                box = boxes.strip('\n')
                box = box.split(',')
                x_min = box[0]
                y_min = box[1]
                x_max = int(box[0]) + int(box[2])
                y_max = int(box[1]) + int(box[3])
                object_name = name_dict[box[5]]

                # if object_name is 'ignored regions' or 'others':
                #     continue

                object = doc.createElement('object')
                nm = doc.createElement('name')
                nm.appendChild(doc.createTextNode(object_name))
                object.appendChild(nm)
                pose = doc.createElement('pose')
                pose.appendChild(doc.createTextNode("Unspecified"))
                object.appendChild(pose)
                truncated = doc.createElement('truncated')
                truncated.appendChild(doc.createTextNode("1"))
                object.appendChild(truncated)
                difficult = doc.createElement('difficult')
                difficult.appendChild(doc.createTextNode("0"))
                object.appendChild(difficult)
                bndbox = doc.createElement('bndbox')
                xmin = doc.createElement('xmin')
                xmin.appendChild(doc.createTextNode(x_min))
                bndbox.appendChild(xmin)
                ymin = doc.createElement('ymin')
                ymin.appendChild(doc.createTextNode(y_min))
                bndbox.appendChild(ymin)
                xmax = doc.createElement('xmax')
                xmax.appendChild(doc.createTextNode(str(x_max)))
                bndbox.appendChild(xmax)
                ymax = doc.createElement('ymax')
                ymax.appendChild(doc.createTextNode(str(y_max)))
                bndbox.appendChild(ymax)
                object.appendChild(bndbox)
                annotation.appendChild(object)
                with open(os.path.join(xml_save_path, file_name + '.xml'), 'w') as x:
                    x.write(doc.toprettyxml())
                x.close()
    f.close()


if __name__ == '__main__':
    t = time.time()
    print('Transfer .txt to .xml...ing....')
    txt_folder = 'annotations'  # visdrone txt标签文件夹
    txt_file = os.listdir(txt_folder)
    img_folder = 'images'  # visdrone 照片所在文件夹

    for txt in txt_file:
        txt_full_path = os.path.join(txt_folder, txt)
        img_full_path = os.path.join(img_folder, txt.split('.')[0] + '.jpg')

        try:
            transfer_to_xml(img_full_path, txt_full_path, txt.split('.')[0])
        except Exception as e:
            print(e)

    print("Transfer .txt to .XML sucessed. costed: {:.3f}s...".format(time.time() - t))

之后删除 visdrone里面存在这样两个类'ignored regions', 'others', 根目录创建两个文件 是另一个大佬的代码 运行第一个.py哦

于2023.3.25更新!!!!!!!!

这个删除类别的代码存在bug 千万不要用 昨天花了50 跑实验得出的结论 常规v5里文件配置成10个类别就好 不需要删除

https://www.cnblogs.com/liliwang/p/12984560.html 大佬链接

"""
File:VOC.py
参考链接:https://github.com/A-mockingbird/VOCdatasetOperation
运行该文件,可以删掉visdrone中的'ignored regions', 'others'两类目标
"""

import sys
import os
import xml.etree.ElementTree as ET
from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
import random
import shutil
import VOCOperationLibrary as vol

class VOC(object):
    def __init__(self, dataset_anno, dataset_img=None, num_class=None, datasetdir=None):
        if os.path.exists(dataset_anno) == False:
            raise  FileNotFoundError
        self.dataset = datasetdir
        self.dataset_anno = dataset_anno
        self.dataset_img = dataset_img
        self.num_class = num_class
        self.dirname = os.path.dirname(self.dataset_anno)
        self.listanno = self._listanno()

    def _listanno(self, annodir=None):
        """return the list of all above of annotation file"""
        if annodir == None:
            annodir = self.dataset_anno
        return os.listdir(annodir)

    def _lowextension(self, imgdir=None):
        return

    def _listimg(self, imgdir=None):
        """return the list of all above of image file"""
        if self.dataset_img == None:
            if imgdir == None:
                print("you should give a image path of dataset in creating VOC class!")
                raise FileNotFoundError
            else:
                return os.listdir(imgdir)
        else:
            return os.listdir(self.dataset_img)

    def _ParseAnnos(self, annodir=None):
        """
        return the information of all above of annotation in this dataset_anno,
        format: a list of dictionary, include file name, annotation, size
        ([{'file', 'info', 'size'}])
        annotation is a list, [cls, xmin, ymin, xmax, ymax]
        size if a tuple, (weight, height)
        """
        annos = []
        if annodir == None:
            annodir = self.dataset_anno
            annolist = self.listanno
        else:
            annolist = self._listanno(annodir)
        for annofile in annolist:
            if annofile[-4:] != ".xml":
                continue
            annotation = vol._parseannotation(os.path.join(annodir, annofile))
            annos.append({'file': annofile, 'info': annotation[0], 'size': annotation[1]})
        return annos

    def _DelAnnotations(self, delclass, annodir=None):
        """
        Delete specific cls
        Precondition:delclass-a list of what's annotaion name you want to delete
        """
        if delclass == '':
            return
        if annodir== None:
            annodir = self.dataset_anno
        annolist = self._listanno(annodir) 
        for annofile in annolist:
            vol._deletesinglefile(os.path.join(annodir, annofile), delclass)

    def _ChangeAnnotation(self, oldcls, newcls, annodir=None):
        """
        Change class name.
        Precondition:
                    oldcls:old class name,string
                    newcls:new class name,string
                    annodir:annotation file direction, if it is None,use self.dataset_dir(init value)
        """
        if annodir == None:
            annodir = self.dataset_anno
        annolist = self._listanno(annodir)
        for annofile in annolist:
            vol._changeone(os.path.join(annodir,annofile), oldcls, newcls)

    # def _Crop(self, imgdir, cropdir, annos=None):
    #     """
    #     To crop all the box region of object in dataset
    #     """
    #     if annos == None:
    #         annos = self._ParseAnnos()
    #     total = len(annos)
    #     for num, annotation in enumerate(annos):
    #         annofile = annotation['file']
    #         if os.path.exists(imgdir+annofile[:-4]+'.jpg') == False:
    #             raise FileNotFoundError
    #         pil_im = Image.open(imgdir+annofile[:-4]+'.jpg')
    #         for i, obj in enumerate(annotation['info']):
    #             obj_class = obj[0]
    #             obj_box = tuple(obj[1:5])
    #             if os.path.exists(cropdir+obj_class) == False:
    #                 os.mkdir(cropdir+obj_class)
    #             region = pil_im.crop(obj_box)
    #             pil_region = Image.fromarray(np.uint8(region))
    #             pil_region.save(os.path.join(cropdir+obj_class,
    #                             annofile[:-4]+'_'+str(i)+'.jpg'))
    #         process = int(num*100 / total)
    #         s1 = "\r%d%%[%s%s]"%(process,"*"*process," "*(100-process))
    #         s2 = "\r%d%%[%s]"%(100,"*"*100)
    #         sys.stdout.write(s1)
    #         sys.stdout.flush()
    #     sys.stdout.write(s2)
    #     sys.stdout.flush()
    #     print('')
    #     print("crop is completed!")
    
    def _Countobject(self, annofile=None):
        """
        Count the label numbers of every class, and print it
        Precondition: annofile-the direction of xml file
        """
        if annofile == None:
            annofile = self.dataset_anno
        annoparse = self._ParseAnnos(annofile)
        count = {}
        for anno in annoparse:
            for obj in anno['info']:
                if obj[0] in count:
                    count[obj[0]] +=1
                else:
                    count[obj[0]] = 1
        for c in count.items():
            print("{}: {}".format(c[0], c[1]))
        return count

    # def _DisplayDirectObjec(self):
    #     """
    #     To display what's box you want to display.
    #     """
    #     imglist = self._listimg()
    #     print("input what object you want display, space between numbers")
    #     parseannos = self._ParseAnnos()
    #     for i, annos in enumerate(parseannos):
    #         print("file name: {0}".format(annos['file'][:-4]))
    #         if annos['info'] == []:
    #             print("This image don't have annotation, so programme step it and go on!")
    #             continue
    #         for j, objs in enumerate(annos['info']):
    #             print('''({}): cls={}, \
    #                 box=[{:0>4d}, {:0>4d}, {:0>4d}, {:0>4d}]'''.format(
    #                 j, objs[0], objs[1], objs[2], objs[3], objs[4]
    #             ))
    #         inputstr = input()
    #         numbers = [int(x) for x in inputstr.split(' ')]
    #         self._displayone(annos['info'], annos['file'], numbers)
    #
    def _displayone(self, objs, annofile, nums):
        """
        display the annotation's box of one image
        Precondition: objs-the box information
                      annofile-annotation file name
                      nums-the object number of annotation which you want display
        """
        im = Image.open(self.dataset_img + annofile[:-4] + '.jpg')
        fig, ax = plt.subplots(figsize=(12, 12))
        ax.imshow(im, aspect='equal')
        for i, obj in enumerate(objs):
            if i in nums:
                bbox = obj[1:]
                ax.add_patch(
                        plt.Rectangle((bbox[0], bbox[1]),
                          bbox[2] - bbox[0],
                          bbox[3] - bbox[1], fill=False,
                          edgecolor='red', linewidth=3.5)
                        )
                ax.text(bbox[0], bbox[1] - 2,
                        '{:s}'.format(obj[0]),
                        bbox=dict(facecolor='blue', alpha=0.5),
                        fontsize=14, color='white')

        plt.axis('off')
        plt.tight_layout()
        plt.draw()
        plt.show()


    def _Mergeannotation(self, newdataset, olddataset=None):
        """
        Merge two dataset anntation information.
        Precondition:
                    newdataset:one dataset annotation path
                    olddataset:one dataset annotation path 
                               and save in this path
        """
        if olddataset == None:
            olddataset = self.dataset_anno
        annolist1 = os.listdir(olddataset)
        annolist2 = os.listdir(newdataset)
        for anno in annolist2:
            if anno in annolist1:
                print(anno)
                vol._mergeone(olddataset+anno, newdataset+anno)
            else:
                shutil.copy(newdataset+anno, olddataset+anno)

    def _Resize(self, newsize, annodir=None, imgdir=None):
        """
        Resize the dataset, include resize all the image into newsize,
        and correct the annotation information.
        Precondition:
                    newsize:the newsize of image
                    annodir:annotation direction
                    imgdir:image direction
        """
        if annodir == None:
            annodir = self.dataset_anno
        if imgdir == None:
            imgdir = self.dataset_img
            if imgdir == None:
                print('Resize operation need a image direction!')
                return
        annolist = self._listanno(annodir)
        imglist = self._listimg(imgdir)
        annos = self._ParseAnnos(annodir)
        total = len(annolist)
        for num, f in enumerate(annolist):
            anno_path = os.path.join(annodir, f)
            img_path = os.path.join(imgdir, f)[:-4] + '.jpg'
            img = Image.open(img_path)
            img = img.resize(newsize)
            img.save(img_path, 'jpeg', quality=95)
            img.close()
            vol._changeone(anno_path, None, None, newsize)
            process = int(num*100 / total)
            s1 = "\r%d%%[%s%s]"%(process,"*"*process," "*(100-process))
            s2 = "\r%d%%[%s]"%(100,"*"*100)
            sys.stdout.write(s1)
            sys.stdout.flush()
        sys.stdout.write(s2)
        sys.stdout.flush()
        print('')
        print('Resize is complete!')
    #
    # def _Splitdataset(self, traintxt, savedir, annodir=None, imgdir=None):
    #     """
    #     Split the dataset into train set and test set, according the train.txt.
    #     Precondition:
    #                 traintxt:train.txt which include the train set file name
    #                 savedir:save direction
    #                 annodir:dataset annotation direction
    #                 imgdir:dataset image direction
    #     Result:
    #         make four direction, trainAnnotations(storage train set's xml file)
    #                              trainJPEGImages(storage train set's image file)
    #                              testAnnotations(storage test set's xml file)
    #                              testJPEGImages(storage test set's image file)
    #     """
    #     if annodir == None:
    #         annodir = self.dataset_anno
    #     if imgdir == None:
    #         if self.dataset_img == None:
    #             print("Please give the path of image!")
    #         else:
    #             imgdir = self.dataset_img
    #     annolist = self._listanno(annodir)
    #     f = open(traintxt, 'r')
    #     trainlist = f.readlines()
    #     f.close()
    #     train_xml_path = os.path.join(savedir, 'trainAnnotations')
    #     trian_img_path = os.path.join(savedir, 'trainJPEGImages')
    #     test_xml_path = os.path.join(savedir, 'testAnnotations')
    #     test_img_path = os.path.join(savedir, 'testJPEGImages')
    #     if os.path.exists(train_xml_path) == False:
    #         os.mkdir(train_xml_path)
    #     if os.path.exists(trian_img_path) == False:
    #         os.mkdir(trian_img_path)
    #     if os.path.exists(test_xml_path) == False:
    #         os.mkdir(train_xml_path)
    #     if os.path.exists(test_img_path) == False:
    #         os.mkdir(test_img_path)
    #     for i in range(len(trainlist)):
    #         trainlist[i] = trainlist[i].replace('\n', '')
    #         annolist.remove(trainlist[i])
    #     testlist = annolist
    #
    #     self._Copy(trainlist, annodir, imgdir, train_xml_path, trian_img_path)
    #     self._Copy(trainlist, annodir, imgdir, test_xml_path, test_img_path)

    # def _Copy(self, xml_list, from_xml_path, from_img_path, save_xml_dir, save_img_dir):
    #     """
    #     Copy the xml file and image file from dataset to save_xml_dir and save_img_dir.
    #     Precondition:
    #                 xml_list:a list of xml file name
    #                 from_xml_path:original xml direction
    #                 from_img_path:original image direction
    #                 save_xml_dir:to save xml direction
    #                 save_img_dir:to save image direction
    #     """
    #     for i, xml in enumerate(xml_list):
    #         shutil.copyfile(os.path.join(from_xml_path, xml),
    #                     os.path.join(save_xml_dir, xml))
    #         shutil.copyfile(os.path.join(from_img_path, xml)[:-4] + '.jpg',
    #                     os.path.join(save_img_dir, xml)[:-4] + '.jpg')
    #
    # def _Find(self, cls, annodir=None):
    #     """
    #     Find files of the direction class object.
    #     Return a list of files name.
    #     Precondition:
    #     cls: a list of class, example:['dog', 'cat']
    #     annodir: the xml files direction
    #     """
    #     if annodir == None:
    #         annodir = self.dataset_anno
    #
    #     annolist = self._listanno(annodir)
    #     xml_files = []
    #     for anno in annolist:
    #         xml = vol._find_one(os.path.join(annodir, anno), cls)
    #         if xml != None:
    #             xml_files.append(xml)
    #     return xml_files
    #
    # def _FindandCopy(self, cls, save_xml_path, save_img_path, annodir=None, imgdir=None):
    #     """
    #     Find files of the direction class object and copy them.
    #     Precondition:
    #                 xml_list:a list of xml file name
    #                 annodir:the dataset xml files direction
    #                 imgdir:the dataset image files direction
    #                 save_xml_dir:to save xml direction
    #                 save_img_dir:to save image direction
    #     """
    #     if imgdir == None:
    #         imgdir = self.dataset_img
    #         if imgdir == None:
    #             print('Copy operation need a image direction!')
    #             return
    #     if annodir == None:
    #         annodir = self.dataset_anno
    #     xml_files = self._Find(cls, annodir)
    #     print(xml_files)
    #     self._Copy(xml_files, annodir, imgdir, save_xml_path, save_img_path)

# v = VOC('F:/数据集/20190122输电线路主要缺陷优化数据集/Annotations/',
#        'F:/数据集/20190122输电线路主要缺陷优化数据集/JPEGImages/')
v = VOC('D:/P2P3P4P5/VOCdevkit/VOC2007/Annotations',
       'D:/P2P3P4P5/VOCdevkit/VOC2007/JPEGImages')

#print(v._ParseAnnos())
#v._Crop('F:/数据集/JPEGImages/', 'F:/数据集/crops/')
v._DelAnnotations(['ignored regions', 'others'])
#v._DisplayDirectObjec()
#size = (512, 512)
#v._Resize(size)
#v._Mergeannotation('C:/Users/91279/Desktop/xml/', 'F:/xml/')
#v._DelAnnotations(['123'])
#cls = ['shockproof hammer deformation', 'shockproof hammer intersection', 'grading ring damage', 'shielded ring corrosion']
#v._FindandCopy(cls, 'F:/数据集/20190122输电线路主要缺陷优化数据集/aaaa/', 'F:/数据集/20190122输电线路主要缺陷优化数据集/bbbb/')
"""
File:VOCOperationLibrary.py
参考链接:https://github.com/A-mockingbird/VOCdatasetOperation
"""

import sys
import os
import xml.etree.ElementTree as ET
import numpy as np
import random
import shutil

def _parseannotation(annofile):
    """
    return a array include class name, box([cls, xmin, ymin, xmax, ymax])
    and a tuple include the size of object((weight, height))
    """
    if os.path.exists(annofile) == False:
        raise FileNotFoundError
    tree = ET.parse(annofile)
    annos = []
    for annoobject in tree.iter():
        if 'size' in annoobject.tag:
            for element in list(annoobject):
                if 'height' in element.tag:
                    height = int(element.text)
                if 'width' in element.tag:
                    weight = int(element.text)
    
    for annoobject in tree.iter():
        if 'object' in annoobject.tag:
            for element in list(annoobject):
                if 'name' in element.tag:
                    name = element.text
                if 'bndbox' in element.tag:
                    for size in list(element):
                        if 'xmin' in size.tag:
                            xmin = size.text
                        if 'ymin' in size.tag:
                            ymin = size.text
                        if 'xmax' in size.tag:
                            xmax = size.text
                        if 'ymax' in size.tag:
                            ymax = size.text
                    annos.append([name, int(xmin), int(ymin), int(xmax), int(ymax)])
    return annos, (weight, height)

def _deletesinglefile(annofile, delclass):
    if os.path.exists(annofile) == False:
        raise FileNotFoundError
    tree = ET.parse(annofile)
    root = tree.getroot()
    annos = [anno for anno in root.iter()]
    for i, anno in enumerate(annos):
        if 'object' in anno.tag:
            for element in list(anno):
                if 'name' in element.tag:
                    if element.text in delclass:
                        root.remove(annos[i])
                        print(os.path.basename(annofile)+' have something deleted')
                break
    tree = ET.ElementTree(root)
    tree.write(annofile, encoding="utf-8", xml_declaration=True)

def _changeone(annofile, oldcls, newcls, newsize=None):
        if os.path.exists(annofile) == False:
            raise FileNotFoundError
        tree = ET.parse(annofile)
        root = tree.getroot()
        annos = [anno for anno in root.iter()]
        for i, anno in enumerate(annos):
            if newsize != None:
                if 'width' in anno.tag:
                    oldwidth = float(anno.text)
                    anno.text = str(newsize[0])
                    sizechangerate_x = newsize[0] / oldwidth
                if 'height' in anno.tag:
                    oldheight = float(anno.text)
                    anno.text = str(newsize[1])
                    sizechangerate_y = newsize[1] / oldheight

            if 'object' in anno.tag:
                for element in list(anno):
                    if oldcls != newcls:
                        if 'name' in element.tag:
                            if element.text == oldcls:
                                element.text = newcls
                                print(os.path.basename(annofile)+' change the class name')
                        break
                    if newsize != None:
                        if 'bndbox' in element.tag:
                            for coordinate in list(element):
                                if 'xmin' in coordinate.tag:
                                    coordinate.text = str(int(int(coordinate.text) * sizechangerate_x))
                                if 'xmax' in coordinate.tag:
                                    coordinate.text = str(int(int(coordinate.text) * sizechangerate_x))
                                if 'ymin' in coordinate.tag:
                                    coordinate.text = str(int(int(coordinate.text) * sizechangerate_y))
                                if 'ymax' in coordinate.tag:
                                    coordinate.text = str(int(int(coordinate.text) * sizechangerate_y))
                        
        tree = ET.ElementTree(root)
        tree.write(annofile, encoding="utf-8", xml_declaration=True)

def _mergeone(anno1, anno2):
        tree = ET.parse(anno1)
        root = tree.getroot()
        annos, size = _parseannotation(anno2)
        if annos == None:
            return
        for annotation in annos:
            appendobj(root, annotation)
        tree.write(anno1, encoding='utf-8', xml_declaration=True)

def appendobj(root, annotation):
    obj = ET.Element('object')
    name = ET.SubElement(obj, 'name')
    name.text = annotation[0]
    pose = ET.SubElement(obj, 'pose')
    pose.text = 'Unspecified'
    truncated = ET.SubElement(obj, 'truncated')
    truncated.text = '0'
    difficult = ET.SubElement(obj, 'difficult')
    difficult.text = '0'
    bndbox = ET.SubElement(obj, 'bndbox')
    xmin = ET.SubElement(bndbox, 'xmin')
    xmin.text = str(annotation[1])
    ymin = ET.SubElement(bndbox, 'ymin')
    ymin.text = str(annotation[2])
    xmax = ET.SubElement(bndbox, 'xmax')
    xmax.text = str(annotation[3])
    ymax = ET.SubElement(bndbox, 'ymax')
    ymax.text = str(annotation[4])
    root.append(obj)
    return root

def _find_one(annofile, cls):
        if os.path.exists(annofile) == False:
            raise FileNotFoundError

        tree = ET.parse(annofile)
        root = tree.getroot()
        annos = [anno for anno in root.iter()]
        
        for i, anno in enumerate(annos):
            if 'object' in anno.tag:
                for element in list(anno):
                        if 'name' in element.tag:
                            if element.text in cls:
                                return os.path.basename(annofile)
                        break                
        
        

你可能感兴趣的:(servlet,java,jvm)