text: # --------------------------------------------------------
  # Fast R-CNN
  # Copyright (c) 2015 Microsoft
  # Licensed under The MIT License [see LICENSE for details]
  # Written by Ross Girshick and Xinlei Chen
  # --------------------------------------------------------
  
  """Compute minibatch blobs for training a Fast R-CNN network."""
  from __future__ import absolute_import
  from __future__ import division
  from __future__ import print_function
  
  import numpy as np
  import numpy.random as npr
  import cv2
  from model.config import cfg
  from utils.blob import prep_im_for_blob, im_list_to_blob
  
  '''
  roidb是由字典组成的list，roidb[img_index]包含了该图片索引所包含到roi信息，下面以roidb[img_index]为例说明：
  boxes：box位置信息，box_num*4的np array
  gt_overlaps：所有box在不同类别的得分，box_num*class_num矩阵
  gt_classes：所有box的真实类别，box_num长度的list
  filpped：是否翻转
  max_overlaps：每个box的在所有类别的得分最大值，box_num长度
  max_classes：每个box的得分最高所对应的类，box_num长度
  image：该图片的路径，字符串
  bbox_targets:每个box的类别，以及与最接近的gt-box的4个方位偏移
  '''
  
  def get_minibatch(roidb, num_classes):
    """Given a roidb, construct a minibatch sampled from it."""
    # 获取roidb中保存的图片数量
    num_images = len(roidb)
    # Sample random scales to use for each image in this batch
    '''
    # Scale to use during training (can list multiple scales)
    # The scale is the pixel size of an image's shortest side
    __C.TRAIN.SCALES = (800,)
    '''
    # 随即生成num_images个下标，对应的是__C.TRAIN.SCALES的值
    # __C.TRAIN.SCALES : 图片被缩放的target_size列表
    # 因为config里面设置__C.TRAIN.SCALES = (800,)，所以得到的random_scale_inds是全0
    random_scale_inds = npr.randint(0, high=len(cfg.TRAIN.SCALES),
                    size=num_images)
    # 要求batchsize必须是图片数量的整数倍
    assert(cfg.TRAIN.BATCH_SIZE % num_images == 0), \
      'num_images ({}) must divide BATCH_SIZE ({})'. \
      format(num_images, cfg.TRAIN.BATCH_SIZE)
  
    # Get the input image blob, formatted for caffe
    # 得到blob和缩放比例。roidb中图片经过了减去均值、缩放操作
    im_blob, im_scales = _get_image_blob(roidb, random_scale_inds)
    # 存入blob字典
    blobs = {'data': im_blob}
  
    assert len(im_scales) == 1, "Single batch only"
    assert len(roidb) == 1, "Single batch only"
    
    # gt boxes: (x1, y1, x2, y2, cls)
    if cfg.TRAIN.USE_ALL_GT:      # __C.TRAIN.USE_ALL_GT = True
      # Include all ground truth boxes
      gt_inds = np.where(roidb[0]['gt_classes'] != 0)[0]      # 获得所有box真实类别的下标
    else:
      # For the COCO ground truth boxes, exclude the ones that are ''iscrowd'' 
      gt_inds = np.where(roidb[0]['gt_classes'] != 0 & np.all(roidb[0]['gt_overlaps'].toarray() > -1.0, axis=1))[0]
    # 整合gt_box信息
    '''
    这点全部用的是roidb[0]，看了其他的函数
    传进来的roidb是通过_get_next_minibatch获取pre-minbatch里面的图片
    然后通过_get_next_minibatch_inds获取图片的下标
    虽然可以改变__C.TRAIN.IMS_PER_BATCH = 2，使每个pre_minbatch为2
    但在train_rpn里面将其修改为1，所以__C.TRAIN.IMS_PER_BATCH = 1
    也就是说其实传进来的roidb只有一个图片的信息，所以下面都用的roidb[0]
    '''
    gt_boxes = np.empty((len(gt_inds), 5), dtype=np.float32)
    gt_boxes[:, 0:4] = roidb[0]['boxes'][gt_inds, :] * im_scales[0]
    gt_boxes[:, 4] = roidb[0]['gt_classes'][gt_inds]
    blobs['gt_boxes'] = gt_boxes
    blobs['im_info'] = np.array(
      [im_blob.shape[1], im_blob.shape[2], im_scales[0]],
      dtype=np.float32)
  
    '''
    blob = np.zeros((num_images, max_shape[0], max_shape[1], 3),
                    dtype=np.float32)
    im_blob.shape[1]代表w, im_blob.shape[2]代表h, im_scales[0]代表缩放比例
    '''
    return blobs
  
  # 对roidb的图像进行缩放，并返回blob、和缩放比例
  def _get_image_blob(roidb, scale_inds):
    """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):
      # roidb[i]['image']这是一个路径,获取路径图片(3维的)
      im = cv2.imread(roidb[i]['image'])
      # 如果之前roi有翻转，水平翻转该图片
      if roidb[i]['flipped']:
        im = im[:, ::-1, :]
      # __C.TRAIN.SCALES = (800,)
      # 因为config就设置了800，没有多的，所有的target_size均为800
      target_size = cfg.TRAIN.SCALES[scale_inds[i]]
      # 对图像进行缩放，返回缩放后的image以及缩放比例
      # prep_im_for_blob再blob.py中
      # __C.PIXEL_MEANS = np.array([[[102.9801, 115.9465, 122.7717]]])
      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
    # im_list_to_blob ：将缩放后的图片放入blob中.（返回blob）
    blob = im_list_to_blob(processed_ims)
  
    return blob, im_scales
  