1. 程式人生 > >py-faster-rcnn中demo.py程式碼與C++版本的程式碼對比: part01 鋪墊, demo.py引入的模組

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的初始化.

————– 分割線 ————–
本系列文章如下: