正如linux下面shell脚本一样,windows下也可以使用DOS批处理脚本文件对文件进行管理。
本文背景
在做人脸识别的时候,开始是在ORL人脸库上测试识别率,所以测试程序是根据ORL的目录结构来写的,(ORL人脸是分类存放的,不同的人脸放在不同的目录下,同一个人的人脸放在同一个目录下)。后来又需要在CASE_PEAL-R1人脸库上进行测试,这是中科院采集的中国人的人脸库,它的目录结构跟ORL不同,它把所有人脸都放在一个目录下,不同人的人脸通过文件名来区分。那么,要在这个库上进行测试,就有两个方案,一是再根据这个目录结构重写一个测试代码,二是把这个目录结构改成跟ORL一样的格式。显然第二种方式更好,如果文件比较少的话,手动创建几个目录,再把文件分类存放就可以了,但是CASE_PEAL-R1人脸库一个子集有几千张人脸图像,显然手动的方式行不通,如果在linux下很容易就想到写一个shell脚本分分钟搞定它,但是又不想把文件拷到linux下转换之后又拷回来,那么最好的方法就是写一个DOS批处理的脚本来处理了。
分类前的人脸库
如下所示,同一个人的人脸图像名称主标识一样,副标识不同,不同的人主标识不一样。
分类程序代码
classify.bat
@echo off & setlocal EnableDelayedExpansion ::延迟变量
set /a cnt=0
set /a num=5
set /a class=0
for %%s in (*.bmp) do ( ::获取当前目录下*.bmp文件
set /a result=!cnt!%%%num%
if !result! equ 0 (::创建目录
set /a class+=1
echo "class=!class!"
mkdir !class!
)
@echo %%s
@move %%s !class!
@set /a cnt+=1
@echo !cnt!
)
pause
以上代码,首先给出了同一个人有5张人脸,然后再遍历当前目录下的所有文件,注意由于人脸库是由文件名来区分类别的,所以遍历的时候每个人的人脸是按先后顺序遍历出的,对于文件名没有这种规律的该程序并不起作用,每遍历5次(
即遍历次数对5求余等于0的时候)就创建一个类别目录,同时将该类别的文件移动到类别目录中。将代码拷贝到一个.txt文本文件中再保存为
classify.bat,把这个文件拷贝到人脸库所在目录,双击运行即可。
这里有个DOS知识点就是,@echo off & setlocal EnableDelayedExpansion ::延迟变量,在这句代码中@表示取消命令回显,即运行的时候DOS终端窗口不会显示命令本身,只会显示结果或错误信息, & setlocal EnableDelayedExpansion ::延迟变量这里是为了在for循环中每次循环都使用变量最新的值,并且使用!变量名!来引用,如果使用%变量名%,只会引用到最初的值和最后的值。
分类后的人脸库
逆分类程序代码
如果像还原成CASE_PEAL-R1本身的目录结构,那么就可以使用下面的代码实现:
unclassify.bat
@echo off & setlocal EnableDelayedExpansion
set /a cnt=0
set /a num=5
set /a class=0
for /r %%s in (*.bmp) do ( ::移出所有文件
echo %%s
move %%s .
)
for /d %%s in (*) do ( ::删除目录
echo %%s
rd %%s
)
pause
这里注意
for /r %%s in (*.bmp) do会遍历当前目录及其子目录以及子目录的子目录等下面的所有*.bmp的图像文件,
for /d %%s in (*) 遍历得到所有子目录名称。
同样把代码拷贝到.txt文件中再另存为unclassify.bat,再把这个文件拷贝到人脸库文件中双击运行,人脸库就还原为原来的目录结构了!