docs: def get_bboxes(
      img,
      mask,
      nb_boxes=100,
      score_thresh=0.5,
      iou_thresh=0.2,
      prop_size=0.09,
      prop_scale=1.2,
  ):
      """
      Uses selective search to generate candidate bounding boxes and keeps the
      ones that have the largest iou with the predicted mask.
  
      :param img: original image
      :param mask: predicted mask
      :param nb_boxes: max number of candidate bounding boxes
      :param score_thresh: scre threshold to consider prediction is True
      :param iou_thresh: iou threshold to consider a candidate is a correct region
      :param prop_size: selective search parameter
      :param prop_scale: selective search parameter, larger prop_scale favorizes
          large boudning boxes
      :return: list of bounding boxes and ious, boudning boxes are tuples (left,
          top, width, height)
      """
      min_size = int(img.shape[0] * prop_size * img.shape[1] * prop_size)
      scale = int(img.shape[0] * prop_scale)
      # TODO: cross validate for multiple values of prop_size, prop_scale, and nb_bboxes
      img_lbl, regions = selectivesearch.selective_search(
          img, scale=scale, sigma=0.8, min_size=min_size
      )
      rect = [None] * nb_boxes
      max_iou = -1 * np.ones(nb_boxes)
      mask = 1.0 * (mask > score_thresh)
      # compute iou for each candidate bounding box and save top nb_bboxes
      for region in regions:
          left, top, width, height = region["rect"]
          intersection = mask[top : top + height, left : left + width].sum()
          union = height * width + mask.sum() - intersection
          iou = intersection / union
          idx = np.argmin(max_iou)
          if iou > max_iou[idx]:
              max_iou[idx] = iou
              rect[idx] = region["rect"]
      # Exclusive maximum
      remove_indexes = max_iou == -1
      bboxes = []
      filtered_ious = []
      for idx in np.argsort([-x for x in max_iou]):
          if remove_indexes[idx]:
              # no more tables bounding boxes
              break
          if len(bboxes) == 0:
              # first candidate table bounding box
              if max_iou[idx] > iou_thresh:
                  bboxes += [rect[idx]]
                  filtered_ious += [max_iou[idx]]
              else:
                  # No tables in this document
                  break
          else:
              # If it doensn't intersect with any other bounding box
              if not any(
                  [do_intersect(rect[idx], bboxes[k]) for k in range(len(bboxes))]
              ):
                  if max_iou[idx] > iou_thresh:
                      bboxes += [rect[idx]]
                      filtered_ious += [max_iou[idx]]
      return bboxes, filtered_ious