这里”C++版本的代码”是指: https://github.com/galian123/cpp_faster_rcnn_detect .
py-faster-rcnn中demo.py代码, 是指 https://github.com/rbgirshick/py-faster-rcnn/blob/master/tools/demo.py 以及
https://github.com/rbgirshick/py-faster-rcnn/tree/master/lib 目录下的一些代码.
涉及到的.py文件都是 https://github.com/rbgirshick/py-faster-rcnn/ 中的.
★ 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的初始化.
————– 分割线 ————–
本系列文章如下:
- (1) py-faster-rcnn中demo.py代码与C++版本的代码对比: part01 铺垫, demo.py引入的模块
- (2) py-faster-rcnn中demo.py代码与C++版本的代码对比: part02 初始化, 创建Net
- (3) py-faster-rcnn中demo.py代码与C++版本的代码对比: part03 处理图片:减掉平均值, resize
- (4) py-faster-rcnn中demo.py代码与C++版本的代码对比: part04 图片转存为blob
- (5) py-faster-rcnn中demo.py代码与C++版本的代码对比: part05 Reshape
- (6) py-faster-rcnn中demo.py代码与C++版本的代码对比: part06 forward, rois boxes transform
- (7) py-faster-rcnn中demo.py代码与C++版本的代码对比: part07 nms, 获取符合条件的boxes