Faster RCNN源码解读2-_anchor_component()为图像建立anchors(核心和关键1)

 

Faster RCNN复现

Faster RCNN源码解读1-整体流程和各个子流程梳理

Faster RCNN源码解读2-_anchor_component()为图像建立anchors(核心和关键1)

Faster RCNN源码解读3.1-_region_proposal() 筛选anchors-_proposal_layer()(核心和关键2)

Faster RCNN源码解读3.2-_region_proposal()筛选anchors-_anchor_target_layer()(核心和关键2)

Faster RCNN源码解读3.3-_region_proposal() 筛选anchors-_proposal_target_layer()(核心和关键2)

Faster RCNN源码解读4-其他收尾工作:ROI_pooling、分类、回归等

Faster RCNN源码解读5-损失函数

 

理论介绍:有关Faster RCNN理论介绍的文章,可以自行搜索,这里就不多说理论部分了。

复现过程:代码配置过程没有记录,具体怎么把源码跑起来需要自己搜索一下。

faster rcnn源码确实挺复杂的,虽然一步步解析了,但是觉得还是没有领会其中的精髓,只能算是略知皮毛。在这里将代码解析的过程给大家分享一下,希望对大家有帮助。先是解析了代码的整体结构,然后对各个子结构进行了分析。代码中的注释,有的是原来就有的注释,有的是参考网上别人的,有的是自己理解的,里面或多或少会有些错误,如果发现,欢迎指正!

本文解析的源码地址:https://github.com/lijianaiml/tf-faster-rcnn-windows

 

本文将lib/layer_utils/snippets.py中generate_anchors_pre_tf()代码摘出来,用特例数据运行一下,看一下它是怎么根据特征图的宽高生成w*h*9个anchors的。

# --------------------------------------------------------
# Tensorflow Faster R-CNN
# Licensed under The MIT License [see LICENSE for details]
# Written by Xinlei Chen
# --------------------------------------------------------
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import tensorflow as tf
import numpy as np

def Mygenerate_anchors():

  array=([[ -83.,  -39.,  100.,   56.],
        [-175.,  -87.,  192.,  104.],
        [-359., -183.,  376.,  200.],
        [ -55.,  -55.,   72.,   72.],
        [-119., -119.,  136.,  136.],
        [-247., -247.,  264.,  264.],
        [ -35.,  -79.,   52.,   96.],
        [ -79., -167.,   96.,  184.],
        [-167., -343.,  184.,  360.]])
  temp = np.array(array)
  return temp


'''
通过特征图宽高,_feat_stride(特征图对原始图缩小的比例)等得到图像上的所有可能的anchors
(坐标可能超出原始图像边界)和anchor数量
generate_anchors_pre_tf步骤如下:
  1,通过_ratio_enum得到anchor时,使用 (0, 0, 15, 15) 的基准窗口,先通过ratio=[0.5,1,2]
  的比例得到anchors。ratio指的是像素总数(宽*高)的比例,而不是宽或者高的比例,
  得到如下三个archor(每个archor为左上角和右下角的坐标):
  2,而后在通过scales=(8, 16, 32)得到放大倍数后的anchors。scales时,将上面的每个都直接放
  大对应的倍数,最终得到9个anchors(每个anchor为左上角和右下角的坐标)。将上面三个anchors
  分别放大就行了,因而本文未给出该图。
  3,之后通过tf.add(anchor_constant, shifts)得到缩放后的每个点的9个anchor在原始图的矩形框。
  anchor_constant:1*9*4。shifts:N*1*4。N为缩放后特征图的像素数。将维度从N*9*4变换到
  (N*9)*4,得到缩放后的图像每个点在原始图像中的anchors。
'''
def generate_anchors_pre_tf(sess,height, width, feat_stride=16, anchor_scales=(8, 16, 32), anchor_ratios=(0.5, 1, 2)):

  #test
  width = 10
  height=5


  shift_x = tf.range(width) * feat_stride # 得到原图的宽  x=tf.range(8.0, 13.0, 2.0) #输出x=[  8.  10.  12.]
  shift_y = tf.range(height) * feat_stride # 得到原图的高
  print("shift_x:",'\n', sess.run(shift_x))
  print("shift_y:",'\n', sess.run(shift_y))

  shift_x, shift_y = tf.meshgrid(shift_x, shift_y) #meshgrid用于从数组a和b产生网格。生成的网格矩阵A和B大小是相同的。
  print("meshgrid_shift_x:",'\n', sess.run(shift_x))
  print("meshgrid_shift_y:",'\n', sess.run(shift_y))

  sx = tf.reshape(shift_x, shape=(-1,))
  sy = tf.reshape(shift_y, shape=(-1,))
  print("sx:",'\n', sess.run(sx))
  print("sy:",'\n', sess.run(sy))

  shifts = tf.transpose(tf.stack([sx, sy, sx, sy])) #tf.transpose() : 对tensor进行转置
  print("shifts:", '\n', sess.run(shifts))
  #tf.stack()是一个矩阵拼接函数,即将秩为 R 的张量列表堆叠成一个秩为 (R+1) 的张量。
  K = tf.multiply(width, height)  #tf.multiply()两个矩阵中对应元素各自相乘
  print("K:", '\n', sess.run(K))

  shifts = tf.transpose(tf.reshape(shifts, shape=[1, K, 4]), perm=(1, 0, 2))
  print("transpose_shifts:", '\n', sess.run(shifts))

  #lib/layer_utils/generate_anchors.py中  根据基准的anchor[0,0,15,15]生成9个基本的anchors
  # anchors = generate_anchors(ratios=np.array(anchor_ratios), scales=np.array(anchor_scales))
  anchors =Mygenerate_anchors()
  A = anchors.shape[0]  #A是基本anchor的数量,值为9
  anchor_constant = tf.constant(anchors.reshape((1, A, 4)), dtype=tf.int32)
  print("anchor_constant:", '\n', sess.run(anchor_constant))

  length = K * A  #K是特征图宽高乘积,这里K*A得到生成anchors的总数

  #通过tf.add(anchor_constant, shifts)得到缩放后的每个点的9个anchor在原始图的矩形框。
  #anchor_constant:1 * 9 * 4。shifts:N * 1 * 4。N为缩放后特征图的像素数。将维度从N * 9 * 4变换到
  #(N * 9) * 4,得到缩放后的图像每个点在原始图像中的anchors。
  anchors_tf = tf.reshape(tf.add(anchor_constant, shifts), shape=(length, 4))
  print("anchors_tf:", '\n', sess.run(anchors_tf))
  print("anchors_tf_length:", '\n', anchors_tf.shape)

  #tf.cast()函数的作用是执行tensorflow中张量数据类型转换,比如读入的图片如果是int8类型的,
  #一般在要在训练前把图像的数据格式转换为float32。
  return tf.cast(anchors_tf, dtype=tf.float32), length


if __name__ == '__main__':
    sess = tf.Session()
    sess.run(tf.global_variables_initializer())
    generate_anchors_pre_tf(sess,5, 10, feat_stride=16, anchor_scales=(8, 16, 32), anchor_ratios=(0.5, 1, 2))

    print('Called with args:')

运行结果:

...(中间部分未截取)

...(中间部分未截取)

 

通过代码和结果的对比,可以很清楚地明白函数是如何根据特征图的w和h生成w*h*9个anchors的,其他的就不多说了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值