前言
首先想要說一下,剛開始我是打算fine-tune一下SSD的,然後我隻需要分類裡面的6類即可,但是SSD給出的VOC資料集标簽中是有21類的,并且各個類别之間還會有交叉,還會有的圖檔有我想要的類别也有沒有我想要的類别,但我隻想将擁有我想要的那6個類的.xml檔案給挑選出來進行訓練,是以就用到了如下的Linux腳本處理方法。後來,我發現在自己制作VOC格式資料的時候,也基本上會用到這些知識,是以就分享一下。當然,本人的Linux shell很渣,隻是想給同樣跟我一樣是Linux小白的同學提供一點幫助。
1.查找所有.xml檔案中有‘person’字元串的檔案,然後将其檔案名輸出:
find -name "*.xml" -exec grep -l 'person' {} \; -fprint out.txt
- 其中需要注意的是,-name後面如果檔案名中有正規表達式的部分,就需要加入”“,如果沒有直接輸入檔案名即可,不用加入雙引号。‘’
- fprint 是将查找到的出書到後面的檔案中,但是這個檔案不會自己建立,必須得先有這個out.txt檔案。
- 這個網址可以查找grep所有的選項:http://www.lampweb.org/linux/3/27.html
2.利用sed删除檔案中每行最前面的”./”字元:
sed -i 's/^..//g' person-test.txt
- -i 的意思是直接在原檔案上修改,’s/’的意思是替換,
3.利用sed将檔案中所有.xml字元替換成.jpg字元:
sed -i 's/\.xml/\.jpg/g' person-test.txt
4.使用python 利用得到的.txt檔案,将檔案中出現的檔案名移動到指定檔案夾:
import shutil
file = open(r'person-test.txt')
n=
for out in file.readlines():
print out
shutil.move("/home/fx/code/caffe-ssd-lw/data/VOCdevkit/VOC2012/JPEGImages/"+out.strip(),"/home/fx/code/caffe-ssd-lw/data/VOCdevkit/VOC2012/PersonImages")
- 其中,shutil子產品中,有我們想要用的.move方法。
- 其中需要注意的是,當這樣拼接字元串”“+out時,字元串會自帶一個“\n”這樣就無法通路到我們想要的檔案路徑,但是我們加入字元串中的.strip()方法,這個方法就可以删除開始或者結尾的空白字元。
5.當得到這些檔案後,我們将他合并到一起。合并有兩種方式一種是粘貼到檔案的後面,一種是同行合并:
直接将2.txt檔案的全部内容粘貼到1.txt檔案的全部内容之後:
将2.txt檔案的全部内容按相同的行号粘貼到1.txt檔案中:
- 其中,-d 的意思就是按 ” 内的字元分開,這裡就打了一個空格,是以粘貼上去的時候就按這一個空格把内容分隔開了。
6.由于有的含有person,bus…這幾類的檔案中,有我們沒有标記的标簽,是以在制作資料的時候報錯,再寫一個小的python程式,把這些xml裡包含未聲明的标簽的檔案給去除掉:
import xml.etree.cElementTree as ET
import os
names = ['person','bicycle','car','bus','motorbike']
n=
directory = open('out.txt')
delete = open('delete.txt','w')
for dir in directory.readlines():
tree = ET.ElementTree(file=dir.strip())
for elem in tree.iter(tag='name'):
if elem.text in names:
print "i get it"
else:
print "i didn't get it"extract
n+=
delete.write(dir)
break
print n
再得到我們想要的delete.txt檔案之後,我們再用一個指令即可得到去除的檔案。
- -v 就是将未比對到的字元輸出。這樣就可以把兩個檔案中不同的東西輸出了。
7.如何将一個檔案中各行的内容打亂。
見該網址即可:http://www.programgo.com/article/522152370/
最後附上在github上問SSD作者如何利用自己資料fine-tune SSD模型,然後作者給出了如下回答:
You should create a labelmap file for your own data using : https://github.com/weiliu89/caffe/blob/ssd/tools/create_label_map.cpp
And currently it only support annotation whose format is same as VOC or COCO. If not, you should write your own function to read the annotation. You can refer to:https://github.com/weiliu89/caffe/blob/ssd/src/caffe/util/io.cpp#L251 (Parse VOC/ILSVRC detection annotation.)
I would also strongly suggest using this to debug before you train on your own data.:https://github.com/weiliu89/caffe/blob/ssd/examples/ssd.ipynb
參考網址:
同時删除兩個檔案中相同的部分:http://www.cnblogs.com/raceblog/archive/2011/03/24/shell-delete-comm.html