将VOC数据集里的local、results、voccode等文件夹和文件如数保留,只更改VOC2007文件夹里的东西,里面包括SegmentationObject、SegmentationClass、JPEGImages、Annotations、ImageSets文件夹,我们的任务是目标检测,所以SegmentationObject和SegmentationClass就不需要了。保留JPEGImages、Annotations、ImageSets文件夹。前提是自己要有数据,即图片和标注好的类别名与坐标。
JPEGImages:把自己所有类别的图片放到JPEGImages文件夹下,图片名按类似于000001.jpg、000002.jpg…的格式,不一定非要按数字顺序,但是一定不要重名,最好归一化一下图片的尺寸。
Annotations:VOCcode中的代码已经提供了写注释文件的东西,文件可以使XML格式,也可以是txt文件格式,因工程而异。我最先生成的是txt格式,转而将txt改成了xml格式。原数据集是csv格式的。下面我会提供matlab下的转换代码, 由于每个人的原数据集格式不一样 ,这里仅供大家参考。
- train.txt 是用来训练的图片文件的文件名列表
- trianval.txt是用来训练和验证的图片文件的文件名列表
- val.txt是用来验证的图片文件的文件名列表
- test.txt 是用来测试的图片文件的文件名列表
- trianval.txt是用来训练和验证的图片文件的文件名列表
- val.txt是用来验证的图片文件的文件名列表
- test.txt 是用来测试的图片文件的文件名列表
1、自己的数据集转voctxt格式:
%%%%我的数据格式是存储在csv文件里的:
%%%%‘stop_1330545910.avi_image0.png;stop;862;104;916;158;0’
clc
close all
clear all;
outpath='...\Annotations\';
if ~exist(outpath,'dir')
mkdir(outpath);
end
image_outpath='...\JPEGImages\';
if ~exist(image_outpath,'dir')
mkdir(image_outpath);
end
%%%%% 读取txt文本数据curtxt='\你要转化格式的标注文件';fprintf('Read my file!\n');fid=fopen(curtxt,'r'); %%打开文件并开始逐行读取while ~feof(fid) cline = fgetl(fid); s=s+1; if s~=2 idx = find(cline==';'); %%%我的数据是以分号隔开的 image_name =cline(1:(idx(1)-1));%%%%这里我没有将名字改为0001、0002... openfile=strcat(outpath,image_name,'.txt');
%%%%同一个图像里的object只需要接着往下写,不需要新建txt。
if ~exist(openfile,'file')
fidOut = fopen(openfile, 'a');
fprintf(fidOut, 'Image filename :%s\r\n',image_name);
getim=imread(image_name);
imwrite(getim,strcat(image_outpath,image_name));
[W,H,C]=size(getim);
fprintf(fidOut, 'Image size (X x Y x C) : %d x %d x %d\r\n', W,H,C);
fprintf(fidOut, 'Database :LTS_DATA\r\n');
fclose(fidOut);
end
fidOut = fopen(openfile, 'a');
class_name=cline(idx(1)+1:(idx(2)-1));
x_min = str2num(cline(idx(2):idx(3)-1));
y_min = str2num(cline(idx(3):idx(4)-1));
x_max = str2num(cline(idx(4):idx(5)-1));
y_max = str2num(cline(idx(5):idx(6)-1));
fprintf(fidOut, 'Bounding box for object %d %s (Xmin, Ymin) - (Xmax, Ymax) : (%d, %d) - (%d, %d)\r\n', k,class_name,x_min,y_min,x_max,y_max);
fclose(fidOut);
end
end
fprintf('%s has Finish!\n',data_root_list(i).name);
end
fprintf('Finish!');
%%%%%%%代码无法拿去即用,需要读者看懂后自己根据自己的数据改写。
2 将数据改成XML格式
%我是根据以上代码现将数据改成txt文件,每行格式为:
% stop_1330545910.avi_image0.png stop 44 28 132 121
%即每行由图片名、目标类型、包围框坐标组成,空格隔开
%如果一张图片有多个目标,则格式如下:(比如两个目标)
%000002.jpg stop 44 28 132 121
%000002.jpg stop 50 27 140 110
clc;
clear;
%注意修改下面三个变量
imgpath='....\GPEGImages\');%图像存放文件夹
txtpath='....\你的txt文件';%txt文件
foldername='Annotations';%xml的folder字段名
fidin=fopen(txtpath,'r');
lastname='begin';
while ~feof(fidin)
tline=fgetl(fidin);
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','0')));
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
if exist('Createnode','var')
tempname=lastname;
tempname=strcat(foldername,lastname,‘.xml’’);
tempname=strcat(tempname,'.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 LISA')));
source_node.appendChild(node);
node=Createnode.createElement('annotation');
node.appendChild(Createnode.createTextNode(sprintf('VOC2007')));
source_node.appendChild(node);
node=Createnode.createElement('image');
node.appendChild(Createnode.createTextNode(sprintf('traffic signs')));
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('LISA')));
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','0')));
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=strcat(foldername,lastname,'.xml');
xmlwrite(tempname,Createnode);
end
end
fclose(fidin);
3 准备Main文件夹中主要用到4个文件:train.txt 、 trianval.txt、val.txt、 test.txt,,这里只需要将文件名存入相应文件夹即可,我的训练集和验证集的比例为5:1,这里不提供代码,因为很简单。