old_contents: import numpy as np
  
  from chainercv.links.model.ssd import encode_with_default_bbox
  from chainercv import transforms
  
  
  class TrainTransformer(object):
  
      def __init__(self, insize, mean, default_bbox, variance):
          self.insize = insize
          self.mean = mean
          self.default_bbox = default_bbox
          self.variance = variance
  
      def __call__(self, in_data):
          img, bbox, label = in_data
  
          # a lot of augmentations come here
  
          _, H, W = img.shape
          x = transforms.resize(img, (self.insize, self.insize))
          x -= np.array(self.mean)[:, np.newaxis, np.newaxis]
          bbox = bbox.copy()
          bbox[:, 0::2] /= W
          bbox[:, 1::2] /= H
          loc, conf = encode_with_default_bbox(
              bbox, label,
              self.default_bbox, self.variance, 0.5)
  
          return x, loc, conf
  
new_contents: import cv2
  import numpy as np
  import random
  
  from chainercv.links.model.ssd import encode_with_default_bbox
  from chainercv import transforms
  from chainercv import utils
  
  
  def _random_crop(img, bbox, label):
      if len(bbox) == 0:
          return img, bbox, label
  
      constraints = (
          (0.1, None),
          (0.3, None),
          (0.5, None),
          (0.7, None),
          (0.9, None),
          (None, 1),
      )
  
      _, H, W = img.shape
  
      crop_bbox = [np.array((0, 0, W, H))]
      for iou_min, iou_max in constraints:
          for _ in range(50):
              if iou_min is None:
                  iou_min = float('-inf')
              if iou_max is None:
                  iou_max = float('inf')
  
              scale = random.uniform(0.3, 1)
              aspect_ratio = random.uniform(
                  max(1 / 2, scale * scale), min(2, 1 / (scale * scale)))
              crop_w = int(W * scale * np.sqrt(aspect_ratio))
              crop_h = int(H * scale / np.sqrt(aspect_ratio))
  
              crop_l = random.randrange(W - crop_w)
              crop_t = random.randrange(H - crop_h)
              crop_bb = np.array((
                  crop_l, crop_t, crop_l + crop_w, crop_t + crop_h))
  
              iou = utils.bbox_iou(bbox, crop_bb[np.newaxis])
              if iou_min <= iou.min() and iou.max() <= iou_max:
                  crop_bbox.append(crop_bb)
                  break
  
      crop_bb = random.choice(crop_bbox)
  
      img = img[:, crop_bb[1]:crop_bb[3], crop_bb[0]:crop_bb[2]]
  
      center = (bbox[:, :2] + bbox[:, 2:]) / 2
      mask = np.logical_and(crop_bb[:2] < center, center < crop_bb[2:]) \
               .all(axis=1)
      bbox = bbox[mask].copy()
      label = label[mask]
  
      bbox[:, :2] = np.maximum(bbox[:, :2], crop_bb[:2])
      bbox[:, :2] -= crop_bb[:2]
      bbox[:, 2:] = np.minimum(bbox[:, 2:], crop_bb[2:])
      bbox[:, 2:] -= crop_bb[:2]
  
      return img, bbox, label
  
  
  class TrainTransformer(object):
  
      def __init__(self, insize, mean, default_bbox, variance):
          self.insize = insize
          self.mean = mean
          self.default_bbox = default_bbox
          self.variance = variance
  
      def __call__(self, in_data):
          img, bbox, label = in_data
  
          # more augmentations here
  
          img, bbox, label = _random_crop(img, bbox, label)
  
          _, H, W = img.shape
          img = transforms.resize(img, (self.insize, self.insize))
          bbox = transforms.resize_bbox(bbox, (W, H), (self.insize, self.insize))
  
          img, params = transforms.random_flip(
              img, x_random=True, return_param=True)
          bbox = transforms.flip_bbox(
              bbox, (self.insize, self.insize), params['x_flip'])
  
          img -= np.array(self.mean)[:, np.newaxis, np.newaxis]
          bbox = transforms.resize_bbox(bbox, (self.insize, self.insize), (1, 1))
          loc, conf = encode_with_default_bbox(
              bbox, label,
              self.default_bbox, self.variance, 0.5)
  
          return img, loc, conf
  
subject: add random_crop