Faster-RCNN-TensorFlow-Python3.5 在Ubuntu16.04下的配置方法
安裝過程
1. 深度學習環境Tensorflow的安裝
參考這一篇博客:https://www.cnblogs.com/pprp/p/9463974.html
2. 安裝python包
cython, python-opencv, easydict,numpy
pip install Cython
pip install opencv-python
pip install matplotlib
opencv 的包下載安裝,安裝教程
-
ImportError: No module named 'PIL'
- solution:
easy_install PIL&pip install image
- solution:
-
ImportError: No module named 'scipy'
-
solution:
pip install numpy pip install scipy
-
-
ImportError: No module named 'lib.utils.cython_bbox'
git clone --recursive https://github.com/rbgirshick/fast-rcnn.git cd $FRCN_ROOT/lib make cp fast-rcnn/lib/utils/cython_bbox.cpython-35m-x86_64-linux-gnu.so Faster-RCNN-TensorFlow-Python3.5/lib/utils/
3. Go to ./data/coco/PythonAPI
Run python setup.py build_ext --inplace
Run python setup.py build_ext install
4. git clone
用git命令將這個庫下載到本地 Faster-RCNN-TensorFlow-Python3.5
git clone https://github.com/dBeker/Faster-RCNN-TensorFlow-Python3.5.git
# 將cython_bbox.cpython-36m-x86_64-linux-gnu.so下載下來
wget https://github.com/pprp/DL/blob/master/cython_bbox.cpython-36m-x86_64-linux-gnu.so
把Faster-RCNN_TF 中的cython_bbox.xxx.so 復制到 lib/utils
cp cython_bbox.cpython-36m-x86_64-linux-gnu.so Faster-RCNN-TensorFlow-Python3.5/lib/utils
5. 下載預訓練模型
Download pre-trained VGG16 from here and place it as "data\imagenet_weights\vgg16.ckpt"
wget http://download.tensorflow.org/models/vgg_16_2016_08_28.tar.gz
unzip vgg*
#重命名為vgg16.ckpt
cp vgg* vgg16.ckpt
#放到以下位置
mv vgg16.ckpt data\imagenet_weights\vgg16.ckpt
6. 自己數據集的制作
-
xml文件的制作需要labelImg軟件的幫助,這里提供在window下的exe包,打開即可使用
wget https://github.com/pprp/DL/blob/master/LabelIMG.zip- 使用方法:
Ctrl + u 加載目錄中的所有圖像,鼠標點擊Open dir同功能 Ctrl + r 更改默認注釋目標目錄(xml文件保存的地址) Ctrl + s 保存 Ctrl + d 復制當前標簽和矩形框 space 將當前圖像標記為已驗證 w 創建一個矩形框 d 下一張圖片 a 上一張圖片 del 刪除選定的矩形框 Ctrl++ 放大 Ctrl-- 縮小 ↑→↓← 鍵盤箭頭移動選定的矩形框 -
數據的放置結構(自己手動建立)
-data
- VOCdevkit2007
- VOC2007
- Annotations (標簽XML文件,用對應的圖片處理工具人工生成的)
- ImageSets (生成的方法是用sh或者MATLAB語言生成)
- Main
- test.txt
- trian.txt
- trainval.txt
- val.txt
- JPEGImages(原始文件)
-
Main中的四個txt文件的制作
詳見附件二,注意要修改路徑位置,最好是絕對路徑
xmlfilepath = 'Annotations'
txtsavepath = 'ImageSets\Main'
7. 替換成自己的數據
將制作好的數據按照以上的目錄結構進行放置
用你的Annotations,ImagesSets和JPEGImages替換…\Faster-RCNN-TensorFlow-Python3.5\data\VOCdevkit2007\VOC2007中對應文件夾
8. 將原始代碼修改為適配你自己的代碼
-
-
Pascal_VOC.py,修改自己的標注的類別
self._classes = ('__background__', # always index 0 'aeroplane', 'bicycle', 'bird', 'boat', 'bottle', 'bus', 'car', 'cat', 'chair', 'cow', 'diningtable', 'dog', 'horse', 'motorbike', 'person', 'pottedplant', 'sheep', 'sofa', 'train', 'tvmonitor')將這些類別替換成你自己的類別。
self.__classes=('__background__', '你的標簽1','你的標簽2',你的標簽3','你的標簽4')
-
-
-
demo.py, 修改為自己的標注類別
CLASSES = ('__background__', 'aeroplane', 'bicycle', 'bird', 'boat', 'bottle', 'bus', 'car', 'cat', 'chair', 'cow', 'diningtable', 'dog', 'horse', 'motorbike', 'person', 'pottedplant', 'sheep', 'sofa', 'train', 'tvmonitor')更改為:
CLASSES = ('__background__', '你的標簽1','你的標簽2',你的標簽3','你的標簽4')
-
-
-
demo.py 更改另外一處代碼:
net.create_architecture(sess, "TEST", 21,tag='default', anchor_scales=[8, 16, 32])更改為:
net.create_architecture(sess, "TEST", 5,tag='default', anchor_scales=[8, 16, 32])原本的代碼是有20類物體+背景,所以是21。 把類別數改為,你的類別+背景。如果是只檢測一類物體,那就改為2
9. 出現的問題
-
- 可能出現以下報錯:
m = cv2.imread(roidb[i][‘image’])
KeyError
解決:
將Faster-RCNN-TensorFlow-Python3.5-master\data\cache文件夾中之前生成的文件模型刪除。
因為會自己讀取cache中的文本,導致訓練出現錯誤。
10. 作出的其他調整
具體方案如下:
-
將demo.py中main函數中進行如下修改:
# ----------------------- # demonet = args.demo_net # dataset = args.dataset # ----------------------- demonet = 'vgg16' dataset = 'pascal_voc' # ----------------------- -
demo.py中main函數中將im_names中的內容替換成自己的測試圖片
im_names = ['IMG_1.jpg', 'IMG_40.jpg', 'IMG_23.jpg', 'IMG_127.jpg', 'IMG_134.jpg', 'IMG_185.jpg']然后將Faster-RCNN-TensorFlow-Python3.5/data/demo中替換上相應的圖片
-
將NETS,DATASETS進行如下修改
NETS = {'vgg16': ('vgg16.ckpt',)}DATASETS = {'pascal_voc': ('voc_2007_trainval',)} -
可以運行了python demo.py
11. 開始訓練
python train.py
12. 跑demo.py
#如果可以直接跑,就直接跑
python demo.py
如果不能運行demo.py,則進行以下處理:
找到通過訓練得到的訓練結果:路徑為:/Faster-RCNN-TensorFlow-Python3.5/default/voc_2007_trainval/default
內容如下:
checkpoint
vgg16.ckpt.data-00000-of-00001
vgg16.ckpt.index
vgg16.ckpt.meta
vgg16_faster_rcnn_iter_10000.ckpt.data-00000-of-00001
vgg16_faster_rcnn_iter_10000.ckpt.index
vgg16_faster_rcnn_iter_10000.ckpt.meta
vgg16_faster_rcnn_iter_10000.pkl
vgg16_faster_rcnn_iter_15000.ckpt.data-00000-of-00001
vgg16_faster_rcnn_iter_15000.ckpt.index
vgg16_faster_rcnn_iter_15000.ckpt.meta
vgg16_faster_rcnn_iter_15000.pkl
vgg16_faster_rcnn_iter_20000.ckpt.data-00000-of-00001
vgg16_faster_rcnn_iter_20000.ckpt.index
vgg16_faster_rcnn_iter_20000.ckpt.meta
vgg16_faster_rcnn_iter_20000.pkl
vgg16_faster_rcnn_iter_25000.ckpt.data-00000-of-00001
vgg16_faster_rcnn_iter_25000.ckpt.index
vgg16_faster_rcnn_iter_25000.ckpt.meta
vgg16_faster_rcnn_iter_25000.pkl
vgg16_faster_rcnn_iter_30000.ckpt.data-00000-of-00001
vgg16_faster_rcnn_iter_30000.ckpt.index
vgg16_faster_rcnn_iter_30000.ckpt.meta
vgg16_faster_rcnn_iter_30000.pkl
vgg16_faster_rcnn_iter_35000.ckpt.data-00000-of-00001
vgg16_faster_rcnn_iter_35000.ckpt.index
vgg16_faster_rcnn_iter_35000.ckpt.meta
vgg16_faster_rcnn_iter_35000.pkl
vgg16_faster_rcnn_iter_40000.ckpt.data-00000-of-00001
vgg16_faster_rcnn_iter_40000.ckpt.index
vgg16_faster_rcnn_iter_40000.ckpt.meta
vgg16_faster_rcnn_iter_40000.pkl
vgg16_faster_rcnn_iter_5000.ckpt.data-00000-of-00001
vgg16_faster_rcnn_iter_5000.ckpt.index
vgg16_faster_rcnn_iter_5000.ckpt.meta
vgg16_faster_rcnn_iter_5000.pkl
vgg16.pkl
將其中的
vgg16_faster_rcnn_iter_40000.ckpt.data-00000-of-00001
vgg16_faster_rcnn_iter_40000.ckpt.index
vgg16_faster_rcnn_iter_40000.ckpt.meta
vgg16_faster_rcnn_iter_40000.pkl
文件復制到以下路徑
/Faster-RCNN-TensorFlow-Python3.5/output/vgg16/voc_2007_trainval/default/
並重命名為:
vgg16.ckpt.data-00000-of-00001
vgg16.ckpt.index
vgg16.ckpt.meta
vgg16.pkl
修改完成,再次運行python demo.py
附件代碼:
- 下面是適用於我本地環境的MATLAB代碼
%注意修改下面四個值
xmlfilepath='/home/pprp/github/Faster-RCNN-TensorFlow-Python3.5/data/VOC2007/Annotations';
txtsavepath='/home/pprp/github/Faster-RCNN-TensorFlow-Python3.5/data/VOC2007/ImageSets/Main';
trainval_percent=0.5; #trainval占整個數據集的百分比,剩下部分就是test所占百分比
train_percent=0.5; #train占trainval的百分比,剩下部分就是val所占百分比
xmlfile=dir(xmlfilepath);
numOfxml=length(xmlfile)-2;#減去.和.. 總的數據集大小
trainval=sort(randperm(numOfxml,floor(numOfxml*trainval_percent)));
test=sort(setdiff(1:numOfxml,trainval));
trainvalsize=length(trainval); #trainval的大小
train=sort(trainval(randperm(trainvalsize,floor(trainvalsize*train_percent))));
val=sort(setdiff(trainval,train));
ftrainval=fopen([txtsavepath 'trainval.txt'],'w');
ftest=fopen([txtsavepath 'test.txt'],'w');
ftrain=fopen([txtsavepath 'train.txt'],'w');
fval=fopen([txtsavepath 'val.txt'],'w');
for i=1:numOfxml
if ismember(i,trainval)
fprintf(ftrainval,'%s\n',xmlfile(i+2).name(1:end-4));
if ismember(i,train)
fprintf(ftrain,'%s\n',xmlfile(i+2).name(1:end-4));
else
fprintf(fval,'%s\n',xmlfile(i+2).name(1:end-4));
end
else
fprintf(ftest,'%s\n',xmlfile(i+2).name(1:end-4));
end
end
fclose(ftrainval);
fclose(ftrain);
fclose(fval);
fclose(ftest);
- Python代碼:
import os
import random
trainval_percent = 0.66
train_percent = 0.5
xmlfilepath = 'Annotations'
txtsavepath = 'ImageSets\Main'
total_xml = os.listdir(xmlfilepath)
num=len(total_xml)
list=range(num)
tv=int(num*trainval_percent)
tr=int(tv*train_percent)
trainval= random.sample(list,tv)
train=random.sample(trainval,tr)
ftrainval = open('ImageSets/Main/trainval.txt', 'w')
ftest = open('ImageSets/Main/test.txt', 'w')
ftrain = open('ImageSets/Main/train.txt', 'w')
fval = open('ImageSets/Main/val.txt', 'w')
for i in list:
name=total_xml[i][:-4]+'\n'
if i in trainval:
ftrainval.write(name)
if i in train:
ftrain.write(name)
else:
fval.write(name)
else:
ftest.write(name)
ftrainval.close()
ftrain.close()
fval.close()
ftest .close()
- 批量修改圖片名稱,以及XML名稱:
import os
import glob
import shutil
# 目錄名稱,你要自己修改
_dir = "H:/mypic/"
file_name = os.listdir(_dir)
print(file_name)
n=1
for file in file_name:
pic_name = os.listdir(_dir+file)
#print(pic_name)
for pic in pic_name:
if os.path.isdir(_dir+file+'/'+pic):
xml_name=os.listdir(_dir+file+"/"+pic)
for xml in xml_name:
shutil.copy( _dir+file+'/'+pic+"/"+xml, 'G:/data/VOCdevkit2007/VOC2007/Annotations/')
# print(pic)
#修改個別XML名稱
# if xml == '1000010.xml':
#print(dir + file + '/' + pic)
# os.rename(_dir+file + '/' + pic + '/' + xml, _dir + file + '/' + pic + "/" + "100010.xml")
# oldname = _dir+file+'/'+pic+"/"+xml
# newname = _dir+file+'/'+pic+"/"+ str(n).zfill(6) + ".xml"
#os.rename(oldname, newname)
#n = n + 1
# print(oldname, '--->', newname)
# zfill是一個自動補零的函數 6 就是一共六位 不足的補零 只有字符串才有這個函數 所以轉換了
# newname = _dir+str(xml_name.index(xml)+1).zfill(6)+".xml"
"""
#批量修改圖片的名稱
n=1
for file in file_name:
pic_name = os.listdir(_dir+file)
print(pic_name)
for pic in pic_name:
oldname = _dir+file+"/"+pic
newname = _dir+file+"/" + str(n).zfill(6) + ".jpg"
os.rename(oldname, newname)
n = n + 1
print(oldname, '--->', newname)
# zfill是一個自動補零的函數 6 就是一共六位 不足的補零 只有字符串才有這個函數 所以轉換了
# newname = _dir+str(xml_name.index(xml)+1).zfill(6)+".xml"
"""
修改對應xml文件
import os
import re
_dir = "G:/Annotations/"
xmlList = os.listdir(_dir)
n = 1
for xml in xmlList:
#f = open(_dir + xml, "r")
f = open(_dir + xml, "r", encoding='utf-8')
xmldata = f.read()
xmldata = re.sub('\<path>(.*?)\</path>', '<path>G:/data/VOCdevkit2007/VOC2007/JPEGImages/' + str(n).zfill(6) + '.jpg</path>', xmldata)
f.close()
f = open(_dir + xml, "w")
f.write(xmldata)
f.close()
n += 1
pascal_voc.py的一些解讀
def init(self, image_set, year,devkit_path=None)
/*這個是初始化函數,它對應着的是pascal_voc的數據集訪問格式,其實我們將其接口修改的更簡單一點*/
def image_path_at(self, i)
/*根據第i個圖像樣本返回其對應的path,其調用了image_path_from_index(self, index)作為其具體實現*/
def image_path_from_index(self, index)
//實現了 image_path的具體功能
def _load_image_set_index(self)
//加載了樣本的list文件
def _get_default_path(self)
//獲得數據集地址
def gt_roidb(self)
//讀取並返回ground_truth(真實值,設定的一個正確的基准)的db
def selective_search_roidb
//讀取並返回ROI的db
def _load_selective_search_roidb(self, gt_roidb)
//加載預選框的文件
def selective_search_IJCV_roidb(self)
//在這里調用讀取Ground_truth和ROI db並將db合並
def _load_selective_search_IJCV_roidb(self, gt_roidb)
//這里是專門讀取作者在IJCV上用的dataset
def _load_pascal_annotation(self, index)
//這個函數是讀取gt的具體實現
def _write_voc_results_file(self, all_boxes)
//voc的檢測結果寫入到文件
def _do_matlab_eval(self, comp_id, output_dir='output')
//根據matlab的evluation接口來做結果的分析
def evaluate_detections
//其調用了_do_matlab_eval
def competition_mode
//設置competitoin_mode,加了一些噪點
