py-faster-rcnn中demo.py程式碼與C++版本的程式碼對比: part01 鋪墊, demo.py引入的模組
★ python程式碼
tools/demo.py 中import的內容, 是整個程式碼流程的鋪墊, 理解了import的內容, 對理解後續的python程式碼和C++ 程式碼都有幫助.
demo.py的import內容:
import _init_paths
from fast_rcnn.config import cfg
from fast_rcnn.test import im_detect
from fast_rcnn.nms_wrapper import nms
import numpy as np
import caffe, os, sys, cv2
♦ _init_paths
import _init_paths
的_init_paths
是指tools/_init_paths.py
其內容如下:
import os.path as osp
import sys
def add_path(path):
if path not in sys.path:
sys.path.insert(0, path)
# 當前目錄是 py-faster-rcnn/tools
this_dir = osp.dirname(__file__)
# Add caffe to PYTHONPATH
caffe_path = osp.join(this_dir, '..' , 'caffe-fast-rcnn', 'python')
add_path(caffe_path)
# Add lib to PYTHONPATH
lib_path = osp.join(this_dir, '..', 'lib')
add_path(lib_path)
可以看到, 將py-faster-rcnn/caffe-fast-rcnn/python
目錄和py-faster-rcnn/lib
目錄新增到了python庫的搜尋路徑列表PYTHONPATH
. 這樣在後續的import時就可以找到了具體的包和模組了.
♦ from fast_rcnn.config import cfg
./lib/fast_rcnn/config.py
demo.py執行過程中的配置基本上都在這裡了. 後續的程式碼流程中會用到這些配置值.
需要注意的是, TEST.HAS_RPN
在demo.py中設定成了True.
config.py中的內容(部分):
__C.TEST = edict()
# Scales to use during testing (can list multiple scales)
# Each scale is the pixel size of an image's shortest side
__C.TEST.SCALES = (600,)
# Max pixel size of the longest side of a scaled input image
__C.TEST.MAX_SIZE = 1000
# Overlap threshold used for non-maximum suppression (suppress boxes with
# IoU >= this threshold)
__C.TEST.NMS = 0.3
# Experimental: treat the (K+1) units in the cls_score layer as linear
# predictors (trained, eg, with one-vs-rest SVMs).
__C.TEST.SVM = False
# Test using bounding-box regressors
__C.TEST.BBOX_REG = True
# Propose boxes
__C.TEST.HAS_RPN = False
# Use GPU implementation of non-maximum suppression
__C.USE_GPU_NMS = True
# Default GPU device id
__C.GPU_ID = 0
♦ from fast_rcnn.test import im_detect
./lib/fast_rcnn/test.py
主要的處理基本上都在這裡了.
♦ from fast_rcnn.nms_wrapper import nms
./lib/fast_rcnn/nms_wrapper.py
from fast_rcnn.config import cfg
# 這裡的nms.gpu_nms是 lib/nms/gpu_nms.so
from nms.gpu_nms import gpu_nms
from nms.cpu_nms import cpu_nms
def nms(dets, thresh, force_cpu=False):
"""Dispatch to either CPU or GPU NMS implementations."""
if dets.shape[0] == 0:
return []
if cfg.USE_GPU_NMS and not force_cpu:
# run here, 呼叫的是gpu_nms.so中的函式
return gpu_nms(dets, thresh, device_id=cfg.GPU_ID)
else:
return cpu_nms(dets, thresh)
♦ import numpy as np
numpy用來處理圖片資料(多維陣列), 尤其是numpy的broadcasting特性, 使得不同維度的陣列可以一起操作(加,減,乘, 除, 等).
♦ import caffe, os, sys, cv2
如果你的py-faster-rcnn是可以用的, 即執行demo.py是沒有問題的, 那麼,可以通過執行python, 並import caffe得知caffe是指py-faster-rcnn/caffe-fast-rcnn/python/caffe
.
$ python
Python 2.7.12 (default, Nov 20 2017, 18:23:56)
[GCC 5.4.0 20160609] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import caffe
>>> help(caffe)
可以看到caffe的幫助資訊:
Help on package caffe: # caffe是一個包
NAME
caffe
FILE # caffe所在的路徑: py-faster-rcnn/caffe-fast-rcnn/python/caffe
/home/<your_name>/path/to/py-faster-rcnn/caffe-fast-rcnn/python/caffe/__init__.py
PACKAGE CONTENTS # caffe包裡的模組, 其中_caffe是c++實現的, pycaffe也是重點關注的
_caffe
classifier
coord_map
detector
draw
io
net_spec
proto (package)
pycaffe
FUNCTIONS #caffe包裡匯出來的函式, 可以供其他python模組呼叫
get_solver(...)
get_solver( (str)arg1) -> Solver :
略
如果import caffe
出現問題, 可以新增/path/to/py-faster-rcnn/caffe-fast-rcnn/python
到PYTHONPATH中:
將下面這句新增到~/.bashrc
中, 然後執行. ~/.bashrc
:
export PYTHONPATH=~/path/to/py-faster-rcnn/caffe-fast-rcnn/python:$PYTHONPATH
♦ caffe
包中的__init__.py
py-faster-rcnn/caffe-fast-rcnn/python/caffe/init.py
from .pycaffe import Net, SGDSolver, NesterovSolver, AdaGradSolver, RMSPropSolver, AdaDeltaSolver, AdamSolver, NCCL, Timer
from ._caffe import init_log, log, set_mode_cpu, set_mode_gpu, set_device, Layer, get_solver, layer_type_list, set_random_seed, solver_count, set_solver_count, solver_rank, set_solver_rank, set_multiprocess, has_nccl
from ._caffe import __version__
from .proto.caffe_pb2 import TRAIN, TEST
from .classifier import Classifier
from .detector import Detector
from . import io
from .net_spec import layers, params, NetSpec, to_proto
從上面可以知道, caffe包依賴了很多模組, 從其他模組中引入了很多函式和類. 這些函式和類可以通過caffe.xxx的形式來使用.
其中from ._caffe import init_log, log, set_mode_cpu, set_mode_gpu, set_device
就是從_caffe.so檔案中, 引入set_mode_cpu
, set_mode_gpu
, set_device
等函式, 最終這些函式將呼叫C++版本的同名函式.
_caffe.so 是執行make pycaffe
時生成的.
執行時所在目錄: py-faster-rcnn/caffe-fast-rcnn/
make pycaffe
CXX/LD -o python/caffe/_caffe.so python/caffe/_caffe.cpp
touch python/caffe/proto/__init__.py
PROTOC (python) src/caffe/proto/caffe.proto
python呼叫C++的方式, 可以參考_caffe.cpp中的boost::python相關的程式碼處理.
接下來分析demo.py的初始化.
————– 分割線 ————–
本系列文章如下: