Matlab按图片分割数据为训练集和测试集并生成label

自己弄数据集,真是非一般的体验呀。虽然说这样算是正在意义上经历一个完整的项目,被迫学习了很多数据处理的问题。但是搞数据真是太蛋疼了。

想了很多方法,但最后发现其实自己整理的数据,最合理的分配训练集和测试集的方法。就是先把数据全部整到一起,然后按一定比例从中随机选出训练集和测试集(这两个肯定是不能重复的),比如这里的25%作为测试集,75%作为训练集。

编写这个程序一开始,主要是有些函数不知道怎么用。编这程序是发现了即使是matlab编写程序都要用disp输出一些信息,这样更方便查看程序运行进度。其余就是新学习了一些函数,再把之前编写的程序合起来。

  1 clear;close all;clc;
  2 %%
  3 %程序实现的功能
  4 %1、把指定路径的数据(已按类别放置在不同的文件夹中),随机的把其中的75%的划分为训练集,25%划分为测试集
  5 %2、训练集按类别放在指定路径的train文件夹中,测试集按类别放在指定路径的val文件夹中
  6 %3、在train和val文件夹的同级文件夹按照caffe需求生成对应的train.txt和val.txt的label
  7 %%
  8 %程序中用到的之前不清楚的函数如下
  9 %1)disp:用来在界面上显示一些必要的信息,方便查看程序进度。disp(\' \')可以起到在界面上换行显示的作用
 10 %2)str2double:带起之前一直使用的str2num,matlab的提示是这样函数效率更高。而且这两个函数输出的数据类型都是double类型。
 11 %3)randperm(n):生成一个1到n直接的随机数列
 12 %4)copyfile(a,b):把文件a复制到路径b,路径b带有最后的\符号
 13 %
 14 %
 15 %
 16 %%
 17 disp(\'程序开始执行\');
 18 %%%%%%需要更改的参数(即两个路径)%%%%%%%%%%%%%%%%%%%%%%%%%%
 19 
 20 pathSource=\'C:\Users\Dy\Desktop\归一化后的图像\sjz\';
 21 
 22 pathDestination=\'C:\Users\Dy\Desktop\归一化后的图像\sjfg\';
 23 
 24 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 25 %在目标路径创建train、val文件夹
 26 pathCreDirTrain=[pathDestination,\'\\',\'train\',\'\\'];
 27 mkdir(pathCreDirTrain);
 28 pathCreDirVal=[pathDestination,\'\\',\'val\',\'\\'];
 29 mkdir(pathCreDirVal);
 30 
 31 
 32 %读取文件夹列表,这种方式读取会保留原文件.(在结构体中第一个)和上一层目录..(在结构体第二个)
 33 dirSourceList=dir(pathSource);
 34 countSourceList=length(dirSourceList);%文件夹个数
 35 %拷贝数据到目标路径
 36 for numDirList=3:countSourceList
 37     if(length(dirSourceList(numDirList).name)>=2)%根据这个过滤掉在此文件夹可能的train.txt、val.txt、count.txt文件
 38         continue;
 39     end    
 40     fileName=dir([pathSource,\'\\',dirSourceList(numDirList).name]);%读取子文件夹中的图片
 41     
 42     %统计子文件夹中的文件个数
 43     fileSum=length(fileName);
 44     fileNum=fileSum-2;%为了生成对应于读取的从3开始的文件,只能先减去2,然后生成随机数后加上2
 45     disp(\' \');%加入一个空格,作为在界面显示中一个类似于换行的工具
 46     %在程序中增加一些输出信息,方便查看数据内容
 47     disp([\'原始数据子文件夹\',num2str(dirSourceList(numDirList).name),\'中有图片:\',num2str(fileNum)]);
 48     
 49     %由于matlab读取文件的规则,在文件列表中肯定最前面会有.和..这两个文件
 50     %所以想到先生成fileSum-2范围内的随机数,然后再各项加2,就为真正要找的随机数
 51     numFileList=randperm(fileNum);
 52     numFileList=numFileList+2;
 53     partitionPosition=round(fileNum/4);%这是通过四舍五入确定的分割位置。
 54     
 55     %在程序中增加一些输出信息,方便查看数据内容
 56 %     disp([\'先拷贝val(前25%)后拷贝train(后75%)\']);
 57     
 58    %%
 59     %拷贝测试集数据val
 60     %在程序中增加一些输出信息,方便查看程序执行进度
 61     disp([\'在val文件夹下创建子文件夹\',num2str(dirSourceList(numDirList).name)]);
 62     disp([\'拷贝\',num2str(partitionPosition),\'张图片到val文件夹下子文件夹\',num2str(dirSourceList(numDirList).name),\'中\']);
 63      
 64     %不知道这种拷贝东西到别的地方,是先拷贝数据量比较多的部分,还是数据量比较少的部分,这有什么讲究。
 65     %在目标val文件夹中,创建对应的子文件夹
 66     pathCreValDir=[pathCreDirVal,dirSourceList(numDirList).name,\'\\'];
 67     mkdir(pathCreValDir);
 68     
 69     %在程序中增加一些输出信息,方便查看程序执行进度
 70     disp([\'复制测试数据到val子文件夹\',num2str(dirSourceList(numDirList).name),\'中\']);
 71     
 72     %复制图片到指定路径
 73     for picNum=1:partitionPosition%由于是要读取numFileList中生成的随机数据,所以从1开始
 74         copyfile([pathSource,\'\\',dirSourceList(numDirList).name,\'\\',fileName(numFileList(picNum)).name], ...
 75             pathCreValDir);
 76     end
 77    %%
 78     %拷贝训练集数据train
 79     %在程序中增加一些输出信息,方便查看程序执行进度
 80     disp([\'在train文件夹下创建子文件夹\',num2str(dirSourceList(numDirList).name)]);
 81     disp([\'拷贝\',num2str(fileNum-partitionPosition),\'张图片到train文件夹下子文件夹\',num2str(dirSourceList(numDirList).name),\'中\']);  
 82     
 83     %在目标train文件夹中,创建对应的子文件夹
 84     pathCreTrainDir=[pathCreDirTrain,dirSourceList(numDirList).name,\'\\'];
 85     mkdir(pathCreTrainDir);  
 86     
 87     %在程序中增加一些输出信息,方便查看程序执行进度
 88     disp([\'复制训练数据到Train子文件夹\',num2str(dirSourceList(numDirList).name),\'中\']);
 89     
 90     %复制图片到指定路径
 91     for picNum=partitionPosition+1:fileNum%由于是要读取numFileList中生成的随机数据,所以从1开始
 92         copyfile([pathSource,\'\\',dirSourceList(numDirList).name,\'\\',fileName(numFileList(picNum)).name], ...
 93             pathCreTrainDir);
 94     end    
 95 end
 96 disp(\'数据拷贝完毕\');
 97 
 98 
 99 %%
100 %生成label
101 disp(\'开始生成label\');
102 %考虑到最好写个程序,能够一步完整所有操作。所以在这程序下面加上生成label的功能
103 %在上面的程序中,已经有变量pathCreDirTrain(目标Train的路径)、pathCreDirVal(目标Val的路径)
104 %先生成train文件夹中的label
105 disp(\'开始生成trainlabel\');
106 dirTrainList=dir(pathCreDirTrain);%读取文件夹列表,这种方式读取会保留原文件.(在结构体中第一个)和上一层目录..(在结构体第二个)
107 countTrainList=length(dirTrainList);%文件夹个数
108 fid = fopen([pathDestination,\'\\',\'train.txt\'], \'w\');%打开train文件夹时,对应的文本文件
109 for numList=3:countTrainList%文件夹从3开始
110     if(length(dirTrainList(numList).name)>=2)%根据这个过滤掉在此文件夹可能的train.txt文件
111         continue;
112     end
113     fileName=dir([pathCreDirTrain,\'\\',dirTrainList(numList).name]);%读取子文件夹
114     fileSum=length(fileName);%统计子文件夹中的文件个数
115     for fileNum=3:fileSum%文件从3开始
116         fprintf(fid,\'%s\', [dirTrainList(numList).name,\'/\',fileName(fileNum).name]);%输入:子文件/图片名称
117         fprintf(fid,\'%s\', \' \');%空格间隔符    
118         fprintf(fid,\'%d\', str2double(dirTrainList(numList).name));%加入label,即文件夹名称
119         fprintf(fid,\'\n\');%换行
120     end
121 end
122 fclose(fid);%关闭文本文件
123 fclose(\'all\');%关闭所有连接,防止没关掉的情况
124 disp(\'trainlabel生成完毕\');
125 
126 %在上面的程序中,已经有变量pathCreDirTrain(目标Train的路径)、pathCreDirVal(目标Val的路径)
127 %先生成train文件夹中的label
128 disp(\'开始生成vallabel\');
129 dirValList=dir(pathCreDirVal);%读取文件夹列表,这种方式读取会保留原文件.(在结构体中第一个)和上一层目录..(在结构体第二个)
130 countValList=length(dirValList);%文件夹个数
131 fid = fopen([pathDestination,\'\\',\'val.txt\'], \'w\');%打开train文件夹时,对应的文本文件
132 for numList=3:countValList%文件夹从3开始
133     if(length(dirValList(numList).name)>=2)%根据这个过滤掉在此文件夹可能的train.txt文件
134         continue;
135     end
136     fileName=dir([pathCreDirVal,\'\\',dirValList(numList).name]);%读取子文件夹
137     fileSum=length(fileName);%统计子文件夹中的文件个数
138     for fileNum=3:fileSum%文件从3开始
139         fprintf(fid,\'%s\', [dirValList(numList).name,\'/\',fileName(fileNum).name]);%输入:子文件/图片名称
140         fprintf(fid,\'%s\', \' \');%空格间隔符    
141         fprintf(fid,\'%d\', str2double(dirValList(numList).name));%加入label,即文件夹名称
142         fprintf(fid,\'\n\');%换行
143     end
144 end
145 fclose(fid);%关闭文本文件
146 fclose(\'all\');%关闭所有连接,防止没关掉的情况
147 disp(\'vallabel生成完毕\');