YOLO训练
一、数据准备
数据转化
数据存储的方式
图片名称存在第一行
接下来每一行存储一个目标框,分别为x坐标,y坐标,w宽,h高,c类别存储的方式如下:
matlab代码如下:
clear
addpath(genpath('VOCdevkit'));%添加转化为xml的工具
fid = fopen('存储图片标注信息的文件');
cnt = 1;
tline = fgetl(fid);
ind = regexp(tline,'\');这个是正则化表达式,返回子串的开始下标和结束下标'
imageName = tline;
imageReName{1} = fullfile(pwd,'path',imageName);%根据你保存图片路径的情况补充为完整的路径
tline = fgetl(fid);
rec{1} = str2num(tline);
tline = fgetl(fid);
imageNum = 1;
while ischar(tline)
while regexp(tline(1),'\d')%这样做的原因:因为我们存储图片名称第一个字符不是数字,这个正则表达的意思是判断第一个字符是否为数字。
rec{imageNum} = [rec{imageNum};str2num(tline)];
tline = fgetl(fid);
end
ind = regexp(tline,'\');%'
imageNum = imageNum + 1;
imageName = tline;
imageReName{imageNum} = fullfile(pwd,'task-action-data/result_temp',imageName);
tline = fgetl(fid);
rec{imageNum} = str2num(tline);
tline = fgetl(fid);
end
%%经过这个处理之后,数据存储的方式是,图片的完整路径存储在imageReName这个结构体里面,标注的信息存储在rec这个结构体里面。
rand_ind = randperm(length(rec));%%'这个是为了进行随机处理,rangperm的功能是生成[0,length(rec)]的不重复的序列。
imageReName = imageReName(rand_ind);%%重新调整顺序
rec = rec(rand_ind);
dataPath = fullfile(pwd,'path');%%创建一个文件夹保存数据即xml文件
if isempty(dir(dataPath))
mkdir(dataPath);
end
rec_tem = VOCreadxml('./VOC2007+2012/VOCdevkit/VOC2007/Annotations/000002xml');
image = imread('./VOC2007+2012/VOCdevkit/VOC2007/JPEGImages/000002.jpg');%%根据实际的路径进行修改
Rec_ter = rec_tem.annotation.object.bndbox;
subplot(1,2,1),imshow(image)%%运行的结果可以看下面展示的图片
subplot(1,2,2),imshow(image(str2double(Rec_ter.ymin):str2double(Rec_ter.ymax),...
str2double(Rec_ter.xmin):str2double(Rec_ter.xmax),:));
attr ={'type1','type2','type3'......'typen'};%%这个根据你的实际情况进行修改
cnt_wrong = 1;%%这个统计一个错误,如图片名称找不到的情况,或者缺少信息。
for n =1:length(imageReName)
if mod(n,10)==0
disp(sprintf('save data to xml: %d....%d',n,length(imageReName)));%%显示当前处理的进度
end
image = imread(imageReName{n});
Rec_ter = rec{n};
Rec_ter2 = Rec_ter;
Rec_ter2(:,3) = Rec_ter2(:,1)+Rec_ter2(:,3);%%xml存储的第一个坐标是xmin,第二个是ymin,第三个是xmax,第四个ymax
Rec_ter2(:,4) = Rec_ter2(:,2)+Rec_ter2(:,4);
Num_object = size(Rec_ter2,1);%%表示目标的个数
[~,Name_ter] = fileparts(imageReName{n});%%这个函数返回的第一个参数是图片的文件夹路径,第二个返回的是图片名称,没有后缀
path_data = fullfile(dataPath,[Name_ter,'.xml']);%%生成保存xml的名称完整路径
%%下面的这个是根据xml里面存储的方式进行数据赋值
Rec_tem_ter = rec_tem;
Rec_tem_ter.annotation.object = [];
Rec_tem_ter.annotation.filename = [Name_ter,'.jpg'];
Rec_tem_ter.annotation.folder = 'fold_name';
Rec_tem_ter.annotation.owner = [];
for kk = 1:Num_object
if size(Rec_ter2(kk,:),2) == 4
cnt_wrong = cnt_wrong+1;
Rec_ter2(kk,5) = 1;
end
Rec_tem_ter.annotation.object(kk).name = attr{Rec_ter2(kk,5)+1};
Rec_tem_ter.annotation.object(kk).pose = [];
Rec_tem_ter.annotation.object(kk).truncated = [];
Rec_tem_ter.annotation.object(kk).difficult = [];
Rec_tem_ter.annotation.object(kk).bndbox.xmin = num2str(Rec_ter2(kk,1));
Rec_tem_ter.annotation.object(kk).bndbox.ymin = num2str(Rec_ter2(kk,2));
Rec_tem_ter.annotation.object(kk).bndbox.xmax = num2str(Rec_ter2(kk,3));
Rec_tem_ter.annotation.object(kk).bndbox.ymax = num2str(Rec_ter2(kk,4));
end
Rec_tem_ter.annotation.segmented = [];
Rec_tem_ter.annotation.size.width = size(image,2);
Rec_tem_ter.annotation.size.height = size(image,1);
Rec_tem_ter.annotation.size.depth = size(image,3);
Rec_tem_ter.annotation.source = [];
VOCwritexml(Rec_tem_ter, path_data);%%保存为xml文件
end
cnt_wrong%%到这里转化xml文件完成。
%%接下来是进行验证保存是否正确
rec_tem = VOCreadxml('保存好的.xml');
image = imread('原始图片.jpg');
for kk = 1:length(rec_tem.annotation.object)
Rec_ter = rec_tem.annotation.object(kk).bndbox;
subplot(1,2,1),imshow(image)
subplot(1,2,2),imshow(image(str2double(Rec_ter.ymin):str2double(Rec_ter.ymax),...
str2double(Rec_ter.xmin):str2double(Rec_ter.xmax),:))
end
%%后面两个文件夹是保存名称,路径。
trainImageFile = fullfile('路径','train.txt');
fid = fopen(trainImageFile,'w');
for n=1:length(imageReName)
fprintf(fid,'%s\n',imageReName{n});
end
fclose(fid)
trainImageFile = fullfile('路径,'data.txt');
fid = fopen(trainImageFile,'w');
for n=1:length(imageReName)
[~,file_ter] = fileparts(imageReName{n});
file_ter = [file_ter '.jpg'];
fprintf(fid,'%s\n',['''',file_ter,'''']);
end
fclose(fid)