1. 程式人生 > >faster r-cnn(python)之路

faster r-cnn(python)之路

WITH_PYTHON_LAYER := 1
USE_CUDNN := 1
  • 將Faster R-CNN下載到本地
git clone --recursive https://github.com/rbgirshick/py-faster-rcnn.git
  • 假設下載下來存放的路徑根目錄為:FRCN_ROOT
  • 編譯Cython模組
cd $FRCN_ROOT/lib
make
  • 編譯caffe和pycaffe
cd $FRCN_ROOT/caffe-fast-rcnn
make -j8 && make pycaffe
  • 下載pre-computed Faster R-CNN detectors
cd $FRCN_ROOT
./data/scripts/fetch_faster_rcnn_models.sh

安裝成功之後,執行demo.py測試下,可以試下自己的圖片:

cd $FRCN_ROOT
./tools/demo.py

2. 資料夾導讀

  • caffe-fast-rcnn:caffe框架目錄
  • data:用來存放pretrained模型以及讀取檔案的cache快取,還有一些下載模型的指令碼
  • experiments:存放配置檔案以及執行的log檔案,另外這個目錄下有scripts,裡面存放end2end和alt_opt兩種訓練方式的指令碼
  • lib:用來存放一些python介面檔案,如其下的datasets主要負責資料庫讀取,config負責一些訓練的配置選項
  • models:裡面存放了三個模型檔案,小型網路ZF,中型網路VGG_CNN_M_1024以及大型網路VGG16,根據你的硬體條件來選擇使用哪種網路,ZF和VGG_CNN_M_1024需要至少3G記憶體,VGG16需要更多的記憶體,但不會超過11G
  • output:這裡存放的是訓練完成後的輸出目錄,這是運行了訓練後才會出現的目錄
  • tools:裡面存放的是訓練和測試的Python檔案

    3. 製作資料集
      3.1.用標註工具labelImg

安裝:sudo pip install labelImg 
執行:labelImg

  這裡寫圖片描述
  可以open一張,也可以open dir匯入一個檔案。利用Create RectBox圈出目標區域,之後對區域進行類別標註。然後利用next image或者prev Image切換下一張或者前一張。標記錯的可以直接點選後delete,….很簡單,不再詳細介紹。
  標註之後儲存後的形式和VOC中的Annotations資料夾中的格式一樣。
  

<annotation verified="no">
  <folder>images</folder>
  <filename>00002</filename>
  <path>/home/apple/work/py-faster-rcnn/images/00002.jpg</path>
  <source>
    <database>Unknown</database>
  </source>
  <size>
    <width>500</width>
    <height>375</height>
    <depth>3</depth>
  </size>
  <segmented>0</segmented>
  <object>
    <name>dog</name>
    <pose>Unspecified</pose>
    <truncated>0</truncated>
    <difficult>0</difficult>
    <bndbox>
      <xmin>2</xmin>
      <ymin>2</ymin>
      <xmax>264</xmax>
      <ymax>372</ymax>
    </bndbox>
  </object>
  <object>
    <name>cat</name>
    <pose>Unspecified</pose>
    <truncated>1</truncated>
    <difficult>0</difficult>
    <bndbox>
      <xmin>276</xmin>
      <ymin>82</ymin>
      <xmax>499</xmax>
      <ymax>375</ymax>
    </bndbox>
  </object>
</annotation>

 2.2.使用自己的程式進行標記

  目標:對影象中目標標註bounding box,標籤以下列形式展現:
  圖片名 目標類別 起始點x座標 y座標 結束點x座標 y座標

00001.jpg car 63 96 180 341
00002.jpg car 85 39 436 330
00003.jpg car 40 43 255 346
00004.jpg car 78 22 433 360
00005.jpg car 147 74 414 370

實現程式碼

# -*- coding: utf-8 -*-
import os
import cv2
import numpy as np

# 當滑鼠按下時變為 True
drawing = False
ix,iy = -1,-1
ox,oy = -1,-1
# 建立回撥函式
def draw_circle(event,x,y,flags,param):
    global ix,iy,ox,oy,drawing
    # 當按下左鍵是返回起始位置座標
    if event==cv2.EVENT_LBUTTONDOWN:
        drawing=True
        ix,iy = x,y
    # 當滑鼠左鍵按下並移動是繪製圖形。 event 可以檢視移動, flag 檢視是否按下
    elif event==cv2.EVENT_MOUSEMOVE and flags==cv2.EVENT_FLAG_LBUTTON:
         if drawing==True:
                cv2.rectangle(image,(ix,iy),(x,y),(0,255,0),-1)
                ox,oy = x,y
    elif event==cv2.EVENT_LBUTTONUP:
        drawing==False

number = 0
jpg = ".jpg"
Image_Path = "./images"
f_wrect = open('images.txt','a')
for file in os.listdir(Image_Path):
    number = number + 1
    #print(number)
    string_number = '%d'%number
    #print(string_number)
    i = len(string_number)
    #print(i)
    while (5 - i) >  0:
        string_number = '0' + string_number
        i = i + 1
    newname = string_number + jpg
    old_NamePath = os.path.join(Image_Path,file)
    new_NamePath = os.path.join(Image_Path,newname)
    os.rename(old_NamePath,new_NamePath)
    image = cv2.imread(new_NamePath)
    cv2.namedWindow('image')
    cv2.setMouseCallback('image',draw_circle)
    while(1):
        cv2.imshow('image',image)
        #執行程式碼,會顯示一張圖片,當按下q鍵時,顯示圖片的視窗被關掉,結束程式。
        if (cv2.waitKey(1)&0xFF==ord('q')):
            print('ok')
            image_rect = newname + ' ceramic '+ '%d'% ix +' '+ '%d'% iy+ ' ' + '%d'% ox + ' ' + '%d'% oy + '\n'
            f_wrect.write(image_rect)
            break
    cv2.destroyWindow('image')

未完待續。。。。。。。。。。

一些不懂的細碎的知識點,可以參考下列部落格:

    np.where()[0] 表示行的索引,
    np.where()[1] 則表示列的索引
    >>> a = np.array((1,2,3))  
    >>> b = np.array((2,3,4))  
    >>> np.hstack((a,b))  
    array([1, 2, 3, 2, 3, 4])  
    >>> a = np.array([[1],[2],[3]])  
    >>> b = np.array([[2],[3],[4]])  
    >>> np.hstack((a,b))  
    array([[1, 2],  
           [2, 3],  
           [3, 4]])  
  • numpy.random.permulation(arrays):返回矩陣洗牌後的副本,意味著原矩陣不變
  • numpy.random.shuffle(arrays):對原資料進行洗牌,卻不返回任何值。
import numpy as np
arrays=np.array([1,2,3,4])
print np.random.permulation(arrays)
print arrays
print np.random.shuffle(arrays)
print arrays

結果:
[4 2 3 1]
[1 2 3 4]#始終不變
None
[1 4 2 3]
  • np.reshape(arrays,(-1,2)):將陣列arrays重新排列成列數為2的。不管-1在第幾個引數的位置,重新排列時均以行為主
[python]程式碼示例:
arrays=np.array([1,2,3,4])
print np.reshape(arrays,(-1,2))
print np.reshape(arrays,(-1,4))
print np.reshape(arrays,(2,-1))
print np.reshape(arrays,(4,-1))

結果:
[[1,2],[3,4]]
[[1,2,3,4]]
[[1,2],[3,4]]
[[1],[2],[3],[4]]