采用tf版本Faster:代码如下
https://github.com/endernewton/tf-faster-rcnn
代码结构:
先给总结:
输入流入脚本的顺序:train_val.py---->layer.py---->minibatch.py
--------------------
下面是具体的每一步处理
-------------------
以训练为例:在lib/model/train_val.py里有如下代码:
from roi_data_layer.layer import RoIDataLayer
......
def train_model(self, sess, max_iters):#训练模型
......
self.data_layer = RoIDataLayer(self.roidb, self.imdb.num_classes)
......
blobs = self.data_layer.forward()
......
调用了RoIDataLayer类,RoIDataLayer实际写在roi_data_layer文件夹里的.layer.py里面。
在layer,py所定义的RoIDataLayer类里面,定义了如下一个类方法:
def forward(self):
"""Get blobs and copy them into this layer's top blob vector."""
blobs = self._get_next_minibatch()
return blobs
这个forward(self)类方法又调用了RoIDataLayer的_get_next_minibatch()类方法,它代码如下:
db_inds = self._get_next_minibatch_inds()
minibatch_db = [self._roidb[i] for i in db_inds]
return get_minibatch(minibatch_db, self._num_classes)
_get_next_minibatch()实际调用了roi_data_layer文件夹里的minibatch.py文件,在minibatch.py里调用的具体代码如下:
def get_minibatch(roidb, num_classes):
"""Given a roidb, construct a minibatch sampled from it."""
im_blob, im_scales = _get_image_blob(roidb, random_scale_inds)
......省略
return blobs
这个函数的的功能是给定图像数据,构建一个blob数据块。就是把数据堆叠在一起。具体实现不全是在这,调用了minibatch.py里的另一个函数,_get_image_blob(),代码很短,如下:
def _get_image_blob(roidb, scale_inds):#组合roi的Blob。
"""Builds an input blob from the images in the roidb at the specified
scales.
"""
num_images = len(roidb)
processed_ims = []
im_scales = []
for i in range(num_images):
im = cv2.imread(roidb[i]['image'])#opencv读入图像的顺序是BGR
if roidb[i]['flipped']:#如果flipped打开了,对图像进行翻转
im = im[:, ::-1, :]
target_size = cfg.TRAIN.SCALES[scale_inds[i]]
im, im_scale = prep_im_for_blob(im, cfg.PIXEL_MEANS, target_size,
cfg.TRAIN.MAX_SIZE)#处理图片
im_scales.append(im_scale)
processed_ims.append(im)#往仓库丢入处理好的图片
# Create a blob to hold the input images
blob = im_list_to_blob(processed_ims)#把处理好的图片堆叠为blob
return blob, im_scales
功能是对每一章图片进行处理,不断的堆叠处理好的数据,得到blob,同时记录每一张输入图片被放缩的大小im_scale(组成im_scales)
具体实现调用了:prep_im_for_blob()以及im_list_to_blob()
后者的代码很简单,张开一个Blob多维数据结构,把处理好的图片一张张丢进去,代码如下:
def im_list_to_blob(ims):
"""Convert a list of images into a network input.
将一组图像转换为网络输入
Assumes images are already prepared (means subtracted, BGR order, ...).
假设图像原料已经准备好:已经取均值、已经转换为BGR结构
"""
#首先一个简短的循环,计算出来图像的最大长宽,作为Blob长宽
max_shape = np.array([im.shape for im in ims]).max(axis=0)
num_images = len(ims)#计算blob高
blob = np.zeros((num_images, max_shape[0], max_shape[1], 3),#按计算出来的长宽高生成数据
dtype=np.float32)
#把每一张图像丢进去
for i in range(num_images):
im = ims[i]
blob[i, 0:im.shape[0], 0:im.shape[1], :] = im
return blob
解析得很清楚了。
主要的最底层的对每一张图片的处理,主要还是prep_im_for_blob()
代码如下:
def prep_im_for_blob(im, pixel_means, target_size, max_size):
"""Mean subtract and scale an image for use in a blob."""
im = im.astype(np.float32, copy=False)
im -= pixel_means#去平均
im_shape = im.shape#求形状
im_size_min = np.min(im_shape[0:2])#求最小边
im_size_max = np.max(im_shape[0:2])#求最大边
im_scale = float(target_size) / float(im_size_min)#求最小边长参数/最小边
# Prevent the biggest axis from being more than MAX_SIZE
if np.round(im_scale * im_size_max) > max_size:
im_scale = float(max_size) / float(im_size_max)
im = cv2.resize(im, None, None, fx=im_scale, fy=im_scale,
interpolation=cv2.INTER_LINEAR)
#说白了上面就是在求原图到输入的缩放比例。
return im, im_scale
这是最底层的实现部分。对应的原理在前段时间写的原理前部分有说明,连接如下:
https://blog.csdn.net/gusui7202/article/details/84556740
问题:问题在于cv2对小图放大的时候,是怎么填充取值的?
放缩用的是opencv 的resize函数,采用的是线性插值。线性插值的原理如下:
------------
2018.12.6-18:00