code: def random_crop_with_bbox_constraints(
      img,
      bbox,
      min_scale=0.3,
      max_scale=1,
      max_aspect_ratio=2,
      constraints=None,
      max_trial=50,
      return_param=False,
  ):
      """Crop an image randomly with bounding box constraints.
  
      This data augmentation is used in training of
      Single Shot Multibox Detector [#]_. More details can be found in
      data augmentation section of the original paper.
  
      .. [#] Wei Liu, Dragomir Anguelov, Dumitru Erhan, Christian Szegedy,
         Scott Reed, Cheng-Yang Fu, Alexander C. Berg.
         SSD: Single Shot MultiBox Detector. ECCV 2016.
  
      Args:
          img (~numpy.ndarray): An image array to be cropped. This is in
              CHW format.
          bbox (~numpy.ndarray): Bounding boxes used for constraints.
              The shape is :math:`(R, 4)`.
              :math:`R` is the number of bounding boxes.
          min_scale (float): The minimum ratio between a cropped
              region and the original image. The default value is :obj:`0.3`.
          max_scale (float): The maximum ratio between a cropped
              region and the original image. The default value is :obj:`1`.
          max_aspect_ratio (float): The maximum aspect ratio of cropped region.
              The default value is :obj:`2`.
          constaraints (iterable of tuples): An iterable of constraints.
              Each constraint should be :obj:`(min_iou, max_iou)` format.
              If you set :obj:`min_iou` or :obj:`max_iou` to :obj:`None`,
              it means not limited.
              If this argument is not specified, :obj:`((0.1, None), (0.3, None),
              (0.5, None), (0.7, None), (0.9, None), (None, 1))` will be used.
          max_trial (int): The maximum number of trials to be conducted
              for each constraint. If this function
              can not find any region that satisfies the constraint in
              :math:`max\_trial` trials, this function skips the constraint.
              The default value is :obj:`50`.
          return_param (bool): If :obj:`True`, this function returns
              information of intermediate values.
  
      Returns:
          ~numpy.ndarray or (~numpy.ndarray, dict):
  
          If :obj:`return_param = False`,
          returns an array :obj:`img` that is cropped from the input
          array.
  
          If :obj:`return_param = True`,
          returns a tuple whose elements are :obj:`img, param`.
          :obj:`param` is a dictionary of intermediate parameters whose
          contents are listed below with key, value-type and the description
          of the value.
  
          * **constraint** (*tuple*): The chosen constraint.
          * **y_slice** (*slice*): A slice in vertical direction used to crop \
              the input image.
          * **x_slice** (*slice*): A slice in horizontal direction used to crop \
              the input image.
  
      """
  
      if constraints is None:
          constraints = (
              (0.1, None),
              (0.3, None),
              (0.5, None),
              (0.7, None),
              (0.9, None),
              (None, 1),
          )
  
      _, H, W = img.shape
      params = [
          {
              "constraint": None,
              "y_slice": slice(0, H),
              "x_slice": slice(0, W),
          }
      ]
  
      if len(bbox) == 0:
          constraints = []
  
      for min_iou, max_iou in constraints:
          if min_iou is None:
              min_iou = 0
          if max_iou is None:
              max_iou = 1
  
          for _ in six.moves.range(max_trial):
              scale = random.uniform(min_scale, max_scale)
              aspect_ratio = random.uniform(
                  max(1 / max_aspect_ratio, scale * scale),
                  min(max_aspect_ratio, 1 / (scale * scale)),
              )
              crop_h = int(H * scale / np.sqrt(aspect_ratio))
              crop_w = int(W * scale * np.sqrt(aspect_ratio))
  
              crop_t = random.randrange(H - crop_h)
              crop_l = random.randrange(W - crop_w)
              crop_bb = np.array(
                  (crop_t, crop_l, crop_t + crop_h, crop_l + crop_w)
              )
  
              iou = utils.bbox_iou(bbox, crop_bb[np.newaxis])
              if min_iou <= iou.min() and iou.max() <= max_iou:
                  params.append(
                      {
                          "constraint": (min_iou, max_iou),
                          "y_slice": slice(crop_t, crop_t + crop_h),
                          "x_slice": slice(crop_l, crop_l + crop_w),
                      }
                  )
                  break
  
      param = random.choice(params)
      img = img[:, param["y_slice"], param["x_slice"]]
  
      if return_param:
          return img, param
      else:
          return img
  
file_path: chainercv/chainercv/links/model/ssd/transforms.py
imports: from __future__ import division
  import numpy
  import random
  import six
  from chainercv import utils
label_desc: Use image node_id 2 for calling a global function with example usage: random_crop_with_bbox_constraints(img, bbox, min_scale, max_scale, max_aspect_ratio, constraints, max_trial, return_param) and returns: img,  param, img