把自己的数据格式转化成VOC2007格式

1. 自己数据集格式介绍

我们数据集标注的文件如下

把自己的数据格式转化成VOC2007格式_第1张图片

每一个image对应一个txt,每个txt内容如下

把自己的数据格式转化成VOC2007格式_第2张图片

每一行有8个数据,每个数据代表的含义如下图所示

把自己的数据格式转化成VOC2007格式_第3张图片2. 重命名

VOC2007格式必须为JPG格式,并且图片是统一的六位数字,从000001开始。那我们也需要将所有训练图片重命名

python代码如下:

# -*- coding: utf-8 -*-
import os
path = "E:\\study_materials\\ECCV Vision Meets Drones Challenge\\datasets\\VisDrone2018-DET-train\\VisDrone2018-DET-train\\images_rename"
filelist = os.listdir(path) #该文件夹下所有的文件(包括文件夹)
count=1
for file in filelist:
    print(file)
for file in filelist:   #遍历所有文件
    Olddir=os.path.join(path,file)   #原来的文件路径
    if os.path.isdir(Olddir):   #如果是文件夹则跳过
        continue
    filename=os.path.splitext(file)[0]   #文件名
    filetype=os.path.splitext(file)[1]   #文件扩展名
    Newdir=os.path.join(path,str(count).zfill(6)+filetype)  #用字符串函数zfill 以0补全所需位数
    os.rename(Olddir,Newdir)#重命名
    count+=1

运行代码之后:

把自己的数据格式转化成VOC2007格式_第4张图片

变成了:

把自己的数据格式转化成VOC2007格式_第5张图片


3. 根据PASCAL VOC数据集制作自己的数据集

我们制作数据集的时候,其实是把我们自己的数据格式转换为PASCAL VOC数据集的格式。

格式如下:

把自己的数据格式转化成VOC2007格式_第6张图片

即每行由图片名、目标类型、包围框坐标组成,空格隔开 
如果一张图片有多个目标,则格式如下:(比如两个目标) 
DG00003L005.jpg iris 187 168 350 253 
DG00003L005.jpg iris 232 86 412 168 

四个坐标点为包围框坐标的左上角和右下角。

所以现在要做的就是把txt文件中的信息先变成如上图所示的格式

小处理:

  • voc2007里面的xml,没有occlusion这个参数,所以暂时忽略。
  • 并且把第五个参数 score为0的都跳过,不考虑。
  • 此比赛存储的是左上角和长宽信息,所以需要转化成左上角和右下角信息。
  • 网上默认xml里面的truncation参数都为0,所以txt里面没有此参数,而我这边生成的txt文件中加入了truncation参数,而且后面matlab转换xml代码中也多了一个str{7}。

转化代码如下:

#include 
#include 
#include 
#include   
#include   
using namespace std;

const string baseFilePath = "E:\\study_materials\\ECCV Vision Meets Drones Challenge\\datasets\\VisDrone2018-DET-train\\VisDrone2018-DET-train\\annotations1\\";
/************************************************************************/
/*  获取文件夹下所有文件名
输入:
path    :   文件夹路径
exd     :   所要获取的文件名后缀,如jpg、png等;如果希望获取所有
文件名, exd = ""
输出:
files   :   获取的文件名列表
*/
/************************************************************************/
void getFiles(string path, string exd, vector& files)
{
	//文件句柄  
	long   hFile = 0;
	//文件信息  
	struct _finddata_t fileinfo;
	string pathName, exdName;

	if (0 != strcmp(exd.c_str(), ""))
	{
		exdName = "\\*." + exd;
	}
	else
	{
		exdName = "\\*";
	}

	if ((hFile = _findfirst(pathName.assign(path).append(exdName).c_str(), &fileinfo)) != -1)
	{
		do
		{
			//如果是文件夹中仍有文件夹,迭代之  
			//如果不是,加入列表  
			if ((fileinfo.attrib &  _A_SUBDIR))
			{
				if (strcmp(fileinfo.name, ".") != 0 && strcmp(fileinfo.name, "..") != 0)
					getFiles(pathName.assign(path).append("\\").append(fileinfo.name), exd, files);
			}
			else
			{
				if (strcmp(fileinfo.name, ".") != 0 && strcmp(fileinfo.name, "..") != 0)
					files.push_back(pathName.assign(/*path).append("\\").append(*/fileinfo.name));
			}
		} while (_findnext(hFile, &fileinfo) == 0);
		_findclose(hFile);
	}
}
int main(){
	vector files;
	vector totalStr;
	getFiles(baseFilePath, "txt", files);
	for (int i = 0; i < files.size(); i++){
		std::cout << files[i] << endl;
		ifstream inf;
		inf.open(baseFilePath+"\\"+files[i], ifstream::in);
		ofstream outf("xml1\\" + files[i]);
		//outf.open("xml\\" + files[k], ifstream::out);

		const int cnt = 8;
		string line;
		string str = "";
		string clsStr = "";
		int j = 0;
		size_t comma = 0;
		size_t comma1 = 0;
		size_t comma2 = 0;

		while (!inf.eof()){
			comma1 = files[i].find('.', 0);
			totalStr.push_back(files[i].substr(0, comma1) + ".jpg");
			//outf << files[i].substr(0, comma1)+".jpg" << ' ';
			getline(inf, line);
			comma = line.find(',', 0);
			str =line.substr(0, comma);
			totalStr.push_back(str);
			//outf << str << ' ';
			while (comma < line.size() && j != cnt - 1){
				comma2 = line.find(',', comma + 1);
				str = line.substr(comma + 1, comma2 - comma - 1);
				totalStr.push_back(str);
				//outf << str << ' ';
				++j;
				comma = comma2;
			}
			//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))
			clsStr = "";
			switch (atoi(totalStr[6].c_str())){
			case 0:
				clsStr = "ignored regions";
				break;
			case 1:
				clsStr = "pedestrian";
				break;
			case 2:
				clsStr = "people";
				break;
			case 3:
				clsStr = "bicycle";
				break;
			case 4:
				clsStr = "car";
				break;
			case 5:
				clsStr = "van";
				break;
			case 6:
				clsStr = "truck";
				break;
			case 7:
				clsStr = "tricycle";
				break;
			case 8:
				clsStr = "awning-tricycle";
				break;
			case 9:
				clsStr = "bus";
				break;
			case 10:
				clsStr = "motor";
				break;
			case 11:
				clsStr = "others";
				break;
			}

			totalStr[6] = clsStr;
			
			//忽略第5个参数 score为0的
			if (totalStr[5] == "0"){
				totalStr.clear();
				j = 0;
			}
			else{
				outf << totalStr[0] << ' ' << totalStr[6] << ' ' << totalStr[1] << ' ' << totalStr[2] << ' '
					<< to_string(atoi(totalStr[1].c_str()) + atoi(totalStr[3].c_str())) << ' '
					<< to_string(atoi(totalStr[2].c_str()) + atoi(totalStr[4].c_str())) << ' '
					<< totalStr[7] << endl;
				totalStr.clear();
				j = 0;
			}	
		}
		inf.close();
		outf.close();
	}
	return 0;
}

4. 把生成的VOC2007格式的txt文件转化成xml形式的

相关链接:

https://blog.csdn.net/Best_Coder/article/details/76577544?locationNum=8&fps=1

把自己的数据格式转化成VOC2007格式_第7张图片


执行步骤:

代码下载后,打开VOC2007xml.m,根据自己情况修改代码,根据在img中提供好的*.jpg 文件与output.txt就可以生成Annotations的xml 文件,如果要生成自己的xml文件,则只需要将img中的图片替换为自己的图片,output.txt根据格式修改就可以了

注意点:

因为这个matlab代码是把所有的txt文件内容合并到一个output.txt里面了,然后根据每行的jpg名称生成对应的xml格式,所以现在需要把所有的txt文件内容合并或者更改matlab代码内容(依次读取所有txt文件)。此处更改了matlab代码。

VOC2007xml.m修改之后的代码如下

%%
clc;
clear;
%注意修改下面四个变量
imgpath='img\';%图像存放文件夹

xmlpath_new='Annotations/';%修改后的xml保存文件夹
foldername='VisDrone2018';%xml的folder字段名
num_begin=1;
namepath=num2str(num_begin,'%06d');
suffix='.txt';
for j=1:6471 %批量处理6471个训练图片(从000001.txt到006471.txt)
    txtpath=[imgpath,namepath,suffix];%txt文件
    fidin=fopen(txtpath,'r');
    lastname='begin';

    while ~feof(fidin)
         tline=fgetl(fidin);
         %if strcmp(tline,'')
             %continue;
         %end
         str = regexp(tline, ' ','split');
         filepath=[imgpath,str{1}];
         img=imread(filepath);
         [h,w,d]=size(img);
          imshow(img);
          rectangle('Position',[str2double(str{3}),str2double(str{4}),str2double(str{5})-str2double(str{3}),str2double(str{6})-str2double(str{4})],'LineWidth',4,'EdgeColor','r');
          pause(0.1);

            if strcmp(str{1},lastname)%如果文件名相等,只需增加object
               object_node=Createnode.createElement('object');
               Root.appendChild(object_node);
               node=Createnode.createElement('name');
               node.appendChild(Createnode.createTextNode(sprintf('%s',str{2})));
               object_node.appendChild(node);

               node=Createnode.createElement('pose');
               node.appendChild(Createnode.createTextNode(sprintf('%s','Unspecified')));
               object_node.appendChild(node);

               node=Createnode.createElement('truncated');
               node.appendChild(Createnode.createTextNode(sprintf('%s',str{7})));
               object_node.appendChild(node);

               node=Createnode.createElement('difficult');
               node.appendChild(Createnode.createTextNode(sprintf('%s','0')));
               object_node.appendChild(node);

               bndbox_node=Createnode.createElement('bndbox');
               object_node.appendChild(bndbox_node);

               node=Createnode.createElement('xmin');
               node.appendChild(Createnode.createTextNode(sprintf('%s',num2str(str{3}))));
               bndbox_node.appendChild(node);

               node=Createnode.createElement('ymin');
               node.appendChild(Createnode.createTextNode(sprintf('%s',num2str(str{4}))));
               bndbox_node.appendChild(node);

               node=Createnode.createElement('xmax');
               node.appendChild(Createnode.createTextNode(sprintf('%s',num2str(str{5}))));
               bndbox_node.appendChild(node);

               node=Createnode.createElement('ymax');
               node.appendChild(Createnode.createTextNode(sprintf('%s',num2str(str{6}))));
               bndbox_node.appendChild(node);
            else %如果文件名不等,则需要新建xml
               copyfile(filepath, 'JPEGImages');
                %先保存上一次的xml
               if exist('Createnode','var')
                  tempname=lastname;
                  tempname=strrep(tempname,'.jpg','.xml');
                  xmlwrite(tempname,Createnode);   
               end


                Createnode=com.mathworks.xml.XMLUtils.createDocument('annotation');
                Root=Createnode.getDocumentElement;%根节点
                node=Createnode.createElement('folder');
                node.appendChild(Createnode.createTextNode(sprintf('%s',foldername)));
                Root.appendChild(node);
                node=Createnode.createElement('filename');
                node.appendChild(Createnode.createTextNode(sprintf('%s',str{1})));
                Root.appendChild(node);
                source_node=Createnode.createElement('source');
                Root.appendChild(source_node);
                node=Createnode.createElement('database');
                node.appendChild(Createnode.createTextNode(sprintf('My Database')));
                source_node.appendChild(node);
                node=Createnode.createElement('annotation');
                node.appendChild(Createnode.createTextNode(sprintf('VisDrone2018-DET-train')));
                source_node.appendChild(node);

               node=Createnode.createElement('image');
               node.appendChild(Createnode.createTextNode(sprintf('flickr')));
               source_node.appendChild(node);

               node=Createnode.createElement('flickrid');
               node.appendChild(Createnode.createTextNode(sprintf('NULL')));
               source_node.appendChild(node);
               owner_node=Createnode.createElement('owner');
               Root.appendChild(owner_node);
               node=Createnode.createElement('flickrid');
               node.appendChild(Createnode.createTextNode(sprintf('NULL')));
               owner_node.appendChild(node);

               node=Createnode.createElement('name');
               node.appendChild(Createnode.createTextNode(sprintf('zhangyuqin')));
               owner_node.appendChild(node);
               size_node=Createnode.createElement('size');
               Root.appendChild(size_node);

              node=Createnode.createElement('width');
              node.appendChild(Createnode.createTextNode(sprintf('%s',num2str(w))));
              size_node.appendChild(node);

              node=Createnode.createElement('height');
              node.appendChild(Createnode.createTextNode(sprintf('%s',num2str(h))));
              size_node.appendChild(node);

             node=Createnode.createElement('depth');
             node.appendChild(Createnode.createTextNode(sprintf('%s',num2str(d))));
             size_node.appendChild(node);

              node=Createnode.createElement('segmented');
              node.appendChild(Createnode.createTextNode(sprintf('%s','0')));
              Root.appendChild(node);
              object_node=Createnode.createElement('object');
              Root.appendChild(object_node);
              node=Createnode.createElement('name');
              node.appendChild(Createnode.createTextNode(sprintf('%s',str{2})));
              object_node.appendChild(node);

              node=Createnode.createElement('pose');
              node.appendChild(Createnode.createTextNode(sprintf('%s','Unspecified')));
              object_node.appendChild(node);

              node=Createnode.createElement('truncated');
              node.appendChild(Createnode.createTextNode(sprintf('%s',str{7})));
              object_node.appendChild(node);

              node=Createnode.createElement('difficult');
              node.appendChild(Createnode.createTextNode(sprintf('%s','0')));
              object_node.appendChild(node);

              bndbox_node=Createnode.createElement('bndbox');
              object_node.appendChild(bndbox_node);

             node=Createnode.createElement('xmin');
             node.appendChild(Createnode.createTextNode(sprintf('%s',num2str(str{3}))));
             bndbox_node.appendChild(node);

             node=Createnode.createElement('ymin');
             node.appendChild(Createnode.createTextNode(sprintf('%s',num2str(str{4}))));
             bndbox_node.appendChild(node);

            node=Createnode.createElement('xmax');
            node.appendChild(Createnode.createTextNode(sprintf('%s',num2str(str{5}))));
            bndbox_node.appendChild(node);

            node=Createnode.createElement('ymax');
            node.appendChild(Createnode.createTextNode(sprintf('%s',num2str(str{6}))));
            bndbox_node.appendChild(node);

           lastname=str{1};
            end
            %处理最后一行
            if feof(fidin)
                tempname=lastname;
                tempname=strrep(tempname,'.jpg','.xml');
                xmlwrite(tempname,Createnode);
            end
    end
    fclose(fidin);

    file=dir(pwd);
    for i=1:length(file)
       if length(file(i).name)>=4 && strcmp(file(i).name(end-3:end),'.xml')
        fold=fopen(file(i).name,'r');
        fnew=fopen([xmlpath_new file(i).name],'w');
        line=1;
        while ~feof(fold)
            tline=fgetl(fold);
            if line==1
               line=2;
               continue;
            end
            expression = '   ';
            replace=char(9);
            newStr=regexprep(tline,expression,replace);
            fprintf(fnew,'%s\n',newStr);
        end
        fprintf('已处理%s\n',file(i).name);
        fclose(fold);
        fclose(fnew);
        delete(file(i).name);
       end
    end
    num_begin=num_begin+1;
    namepath=num2str(num_begin,'%06d'); %从000001变为000002
    %disp(namepath);
end

你可能感兴趣的:(把自己的数据格式转化成VOC2007格式)