예제 #1
0
def compute_detection(Outputs,
                      Anchors,
                      ih,
                      iw,
                      num_classes,
                      score_threshold=0.5,
                      overlap_threshold=0.7,
                      only_anchor=False,
                      max_det_num=100):
    """Post processing outputs of single shot detection
    Params:
    Outpus: a list of (rpn_cls, rpn_boxes)
    Outpus: a list of anchors
    """
    _, rpn_box, rpn_prob = Outputs
    n = cfg.batch_size

    assert Anchors.shape[0] * n == rpn_prob.shape[0] == rpn_box.shape[0], \
        'shape dont match'

    rpn_box_ = rpn_box.copy()
    if only_anchor:
        rpn_box_[...] = 0.0

    out_dim = rpn_box.shape[0] / n
    Dets = []
    for i in range(n):
        s, e = i * out_dim, (i + 1) * out_dim
        bboxes = rpn_box_[s:e]
        probs = rpn_prob[s:e]
        final_boxes, _, _ = anchor.decode(bboxes, probs, Anchors, ih, iw,
                                          num_classes)
        dets = []
        for j in xrange(1, num_classes):
            inds = np.where(probs[:, j] > score_threshold)[0]
            probs_selected = probs[inds, j]
            boxes_selected = final_boxes[inds, :]
            cls_dets = np.hstack(
                (boxes_selected,
                 probs_selected[:, np.newaxis])).astype(np.float32, copy=False)
            if False:
                keep, clusters = nms_multianchor(cls_dets, overlap_threshold)
                if only_anchor:
                    cls_dets = cls_dets[keep, :]
                else:
                    cls_dets = dets_cluster(cls_dets, keep, clusters)
            if True:
                keep = nms(cls_dets, overlap_threshold)
                cls_dets = cls_dets[keep, :]
            tmp_det = np.zeros([cls_dets.shape[0], 6])
            tmp_det[:, 0:5] = cls_dets
            tmp_det[:, 5] = j  # class-label
            dets.append(tmp_det)
        dets = np.vstack(dets)
        order = dets[:, 4].argsort()[::-1]
        dets = dets[order, :]
        Dets.append(dets[:max_det_num, :])
    return Dets
예제 #2
0
def sample_rpn_outputs(boxes, scores, is_training=False, only_positive=False):
    """Sample boxes according to scores and some learning strategies
  assuming the first class is background
  Params:
  boxes: of shape (..., Ax4), each entry is [x1, y1, x2, y2], the last axis has k*4 dims
  scores: of shape (..., A), probs of fg, in [0, 1]
  """
    min_size = cfg.FLAGS.min_size
    rpn_nms_threshold = cfg.FLAGS.rpn_nms_threshold
    pre_nms_top_n = cfg.FLAGS.pre_nms_top_n
    post_nms_top_n = cfg.FLAGS.post_nms_top_n
    if not is_training:
        pre_nms_top_n = int(pre_nms_top_n / 2)
        post_nms_top_n = int(post_nms_top_n / 2)

    boxes = boxes.reshape((-1, 4))
    scores = scores.reshape((-1, 1))

    # filter backgrounds
    # Hope this will filter most of background anchors, since a argsort is too slow..
    if only_positive:
        keeps = np.where(scores > 0.5)[0]
        boxes = boxes[keeps, :]
        scores = scores[keeps]

    # filter minimum size
    keeps = _filter_boxes(boxes, min_size=min_size)
    boxes = boxes[keeps, :]
    scores = scores[keeps]

    # filter with scores
    order = scores.ravel().argsort()[::-1]
    if pre_nms_top_n > 0:
        order = order[:pre_nms_top_n]
    boxes = boxes[order, :]
    scores = scores[order]

    # filter with nms
    det = np.hstack((boxes, scores)).astype(np.float32)
    keeps = nms_wrapper.nms(det, rpn_nms_threshold)

    if post_nms_top_n > 0:
        keeps = keeps[:post_nms_top_n]
    boxes = boxes[keeps, :]
    scores = scores[keeps]
    batch_inds = np.zeros([boxes.shape[0]], dtype=np.int32)

    if _DEBUG:
        LOG('SAMPLE: %d rois has been choosen' % len(keeps))
        LOG('SAMPLE: a positive box: %d %d %d %d %.4f' %
            (boxes[0, 0], boxes[0, 1], boxes[0, 2], boxes[0, 3], scores[0]))
        hs = boxes[:, 3] - boxes[:, 1]
        ws = boxes[:, 2] - boxes[:, 0]
        assert min(np.min(hs), np.min(ws)) > 0, 'invalid boxes'

    return boxes, scores, batch_inds
예제 #3
0
def sample_rpn_outputs(boxes, scores, is_training=False, only_positive=False):
    """Sample boxes according to scores and some learning strategies
  assuming the first class is background
  Params:
  boxes: of shape (..., Ax4), each entry is [x1, y1, x2, y2], the last axis has k*4 dims
  scores: of shape (..., A), foreground prob
  """
    min_size = cfg.FLAGS.min_size
    rpn_nms_threshold = cfg.FLAGS.rpn_nms_threshold
    pre_nms_top_n = cfg.FLAGS.pre_nms_top_n
    post_nms_top_n = cfg.FLAGS.post_nms_top_n
    if not is_training:
        pre_nms_top_n = int(pre_nms_top_n / 2)
        post_nms_top_n = int(post_nms_top_n / 2)

    boxes = boxes.reshape((-1, 4))
    scores = scores.reshape((-1, 1))

    # filter backgrounds
    # Hope this will filter most of background anchors, since a argsort is too slow..
    if only_positive:
        keeps = np.where(scores > 0.5)[0]
        boxes = boxes[keeps, :]
        scores = scores[keeps]

    # filter minimum size
    keeps = _filter_boxes(boxes, min_size=min_size)
    boxes = boxes[keeps, :]
    scores = scores[keeps]

    # filter with scores
    order = scores.ravel().argsort()
    if cfg.FLAGS.pre_nms_top_n > 0:
        order = order[:pre_nms_top_n]
    boxes = boxes[order, :]
    scores = scores[order]

    # filter with nms
    det = np.hstack((boxes, scores)).astype(np.float32)
    keeps = nms_wrapper.nms(det, rpn_nms_threshold)

    if cfg.FLAGS.post_nms_top_n > 0:
        keeps = keeps[:post_nms_top_n]
    boxes = boxes[keeps, :]
    scores = scores[keeps]
    LOG('%d rois has been choosen' % len(keeps))

    return boxes, scores
예제 #4
0
def _apply_nms(boxes, scores, threshold = 0.5):
  """After this only positive boxes are left
  Applying this class-wise
  """
  num_class = scores.shape[1]
  assert boxes.shape[0] == scores.shape[0], \
    'Shape dismatch {} vs {}'.format(boxes.shape, scores.shape)
  
  final_boxes = []
  final_scores = []
  for cls in np.arange(1, num_class):
    cls_boxes = boxes[:, 4*cls: 4*cls+4]
    cls_scores = scores[:, cls]
    dets = np.hstack((cls_boxes, cls_scores[:, np.newaxis]))
    keep = nms_wrapper.nms(dets, thresh=0.3)
    dets = dets[keep, :]
    dets = dets[np.where(dets[:, 4] > threshold)]
    final_boxes.append(dets[:, :4])
    final_scores.append(dets[:, 4])
  
  final_boxes = np.vstack(final_boxes)
  final_scores = np.vstack(final_scores)
  
  return final_boxes, final_scores
예제 #5
0
def _apply_nms(boxes, scores, threshold=0.5):
    """After this only positive boxes are left
  Applying this class-wise
  """
    num_class = scores.shape[1]
    assert boxes.shape[0] == scores.shape[0], \
      'Shape dismatch {} vs {}'.format(boxes.shape, scores.shape)

    final_boxes = []
    final_scores = []
    for cls in np.arange(1, num_class):
        cls_boxes = boxes[:, 4 * cls:4 * cls + 4]
        cls_scores = scores[:, cls]
        dets = np.hstack((cls_boxes, cls_scores[:, np.newaxis]))
        keep = nms_wrapper.nms(dets, thresh=0.3)
        dets = dets[keep, :]
        dets = dets[np.where(dets[:, 4] > threshold)]
        final_boxes.append(dets[:, :4])
        final_scores.append(dets[:, 4])

    final_boxes = np.vstack(final_boxes)
    final_scores = np.vstack(final_scores)

    return final_boxes, final_scores
예제 #6
0
def sample_rpn_outputs(boxes, scores, is_training=False, only_positive=False):
  """Sample boxes according to scores and some learning strategies
  assuming the first class is background
  Params:
  boxes: of shape (..., Ax4), each entry is [x1, y1, x2, y2], the last axis has k*4 dims
  scores: of shape (..., A), probs of fg, in [0, 1]
  """
  min_size = cfg.FLAGS.min_size
  rpn_nms_threshold = cfg.FLAGS.rpn_nms_threshold
  pre_nms_top_n = cfg.FLAGS.pre_nms_top_n
  post_nms_top_n = cfg.FLAGS.post_nms_top_n

  # training: 12000, 2000
  # testing: 6000, 400
  if not is_training:
    pre_nms_top_n = int(pre_nms_top_n / 2)
    post_nms_top_n = int(post_nms_top_n / 5)
    
  boxes = boxes.reshape((-1, 4))
  scores = scores.reshape((-1, 1))
  assert scores.shape[0] == boxes.shape[0], 'scores and boxes dont match'
  
  # filter backgrounds
  # Hope this will filter most of background anchors, since a argsort is too slow..
  if only_positive:
    keeps = np.where(scores > 0.5)[0]
    boxes = boxes[keeps, :]
    scores = scores[keeps]
  
  # filter minimum size
  keeps = _filter_boxes(boxes, min_size=min_size)
  boxes = boxes[keeps, :]
  scores = scores[keeps]
  
  # filter with scores
  order = scores.ravel().argsort()[::-1]
  if pre_nms_top_n > 0:
    order = order[:pre_nms_top_n]
  boxes = boxes[order, :]
  scores = scores[order]

  # filter with nms
  det = np.hstack((boxes, scores)).astype(np.float32)
  keeps = nms_wrapper.nms(det, rpn_nms_threshold)
  
  if post_nms_top_n > 0:
    keeps = keeps[:post_nms_top_n]
  boxes = boxes[keeps, :]
  scores = scores[keeps]
  batch_inds = np.zeros([boxes.shape[0]], dtype=np.int32)

  # # random sample boxes
  ## try early sample later
  # fg_inds = np.where(scores > 0.5)[0]
  # num_fgs = min(len(fg_inds.size), int(rois_per_image * fg_roi_fraction))

  if _DEBUG:
    LOG('SAMPLE: %d rois has been choosen' % len(scores))
    LOG('SAMPLE: a positive box: %d %d %d %d %.4f' % (boxes[0, 0], boxes[0, 1], boxes[0, 2], boxes[0, 3], scores[0]))
    LOG('SAMPLE: a negative box: %d %d %d %d %.4f' % (boxes[-1, 0], boxes[-1, 1], boxes[-1, 2], boxes[-1, 3], scores[-1]))
    hs = boxes[:, 3] - boxes[:, 1]
    ws = boxes[:, 2] - boxes[:, 0]
    assert min(np.min(hs), np.min(ws)) > 0, 'invalid boxes'
  
  return boxes, scores.astype(np.float32), batch_inds
예제 #7
0
def sample_rpn_outputs(boxes, scores, is_training=False, only_positive=False):
    """Sample boxes according to scores and some learning strategies
  assuming the first class is background
  Params:
  boxes: of shape (..., Ax4), each entry is [x1, y1, x2, y2], the last axis has k*4 dims
  scores: of shape (..., A), probs of fg, in [0, 1]
  #but the boxex are allready in form [-1,4] also scores is in shape [-1,1]
  """
    min_size = cfg.FLAGS.min_size
    rpn_nms_threshold = cfg.FLAGS.rpn_nms_threshold
    pre_nms_top_n = cfg.FLAGS.pre_nms_top_n
    post_nms_top_n = cfg.FLAGS.post_nms_top_n

    # training: 12000, 2000
    # testing: 6000, 400
    if not is_training:
        pre_nms_top_n = int(pre_nms_top_n / 2)
        post_nms_top_n = int(post_nms_top_n / 5)

    boxes = boxes.reshape((-1, 4))
    scores = scores.reshape((-1, 1))
    assert scores.shape[0] == boxes.shape[0], 'scores and boxes dont match'

    # filter backgrounds
    # Hope this will filter most of background anchors, since a argsort is too slow..
    if only_positive:
        keeps = np.where(scores > 0.5)[0]
        boxes = boxes[keeps, :]
        scores = scores[keeps]

    # filter minimum size
    keeps = _filter_boxes(boxes, min_size=min_size)
    boxes = boxes[keeps, :]
    scores = scores[keeps]

    # filter with scores
    order = scores.ravel().argsort()[::-1]
    if pre_nms_top_n > 0:
        order = order[:pre_nms_top_n]
    boxes = boxes[order, :]
    scores = scores[order]

    # filter with nms
    det = np.hstack((boxes, scores)).astype(np.float32)
    keeps = nms_wrapper.nms(det, rpn_nms_threshold)

    if post_nms_top_n > 0:
        keeps = keeps[:post_nms_top_n]
    boxes = boxes[keeps, :]
    scores = scores[keeps]
    batch_inds = np.zeros([boxes.shape[0]], dtype=np.int32)

    # # random sample boxes
    ## try early sample later
    # fg_inds = np.where(scores > 0.5)[0]
    # num_fgs = min(len(fg_inds.size), int(rois_per_image * fg_roi_fraction))

    if _DEBUG:
        LOG('SAMPLE: %d rois has been choosen' % len(scores))
        LOG('SAMPLE: a positive box: %d %d %d %d %.4f' %
            (boxes[0, 0], boxes[0, 1], boxes[0, 2], boxes[0, 3], scores[0]))
        LOG('SAMPLE: a negative box: %d %d %d %d %.4f' %
            (boxes[-1, 0], boxes[-1, 1], boxes[-1, 2], boxes[-1,
                                                             3], scores[-1]))
        hs = boxes[:, 3] - boxes[:, 1]
        ws = boxes[:, 2] - boxes[:, 0]
        assert min(np.min(hs), np.min(ws)) > 0, 'invalid boxes'

    return boxes, scores.astype(np.float32), batch_inds
예제 #8
0
def sample_rcnn_outputs(boxes, classes, prob, indexs, class_agnostic=True):

    min_size = cfg.FLAGS.min_size
    mask_nms_threshold = cfg.FLAGS.mask_nms_threshold
    post_nms_inst_n = cfg.FLAGS.post_nms_inst_n
    if class_agnostic is True:
        scores = prob[range(prob.shape[0]), classes]

        boxes = boxes.reshape((-1, 4))
        scores = scores.reshape((-1, 1))
        indexs = indexs.reshape((-1, 1))
        assert scores.shape[0] == boxes.shape[0], 'scores and boxes dont match'

        # filter background
        keeps = np.where(classes != 0)[0]
        scores = scores[keeps]
        indexs = indexs[keeps]
        boxes = boxes[keeps, :]
        classes = classes[keeps]
        prob = prob[keeps, :]

        # filter minimum size
        keeps = _filter_boxes(boxes, min_size=min_size)
        scores = scores[keeps]
        indexs = indexs[keeps]
        boxes = boxes[keeps, :]
        classes = classes[keeps]
        prob = prob[keeps, :]

        #filter with scores
        keeps = np.where(scores > 0.5)[0]
        scores = scores[keeps]
        indexs = indexs[keeps]
        boxes = boxes[keeps, :]
        classes = classes[keeps]
        prob = prob[keeps, :]

        # filter with nms
        order = scores.ravel().argsort()[::-1]
        scores = scores[order]
        indexs = indexs[order]
        boxes = boxes[order, :]
        classes = classes[order]
        prob = prob[order, :]

        det = np.hstack((boxes, scores)).astype(np.float32)
        keeps = nms_wrapper.nms(det, mask_nms_threshold)

        # filter low score
        if post_nms_inst_n > 0:
            keeps = keeps[:post_nms_inst_n]
        scores = scores[keeps]
        indexs = indexs[keeps]
        boxes = boxes[keeps, :]
        classes = classes[keeps]
        prob = prob[keeps, :]

        # quick fix for tensorflow error when no bbox presents
        #@TODO
        if len(classes) is 0:
            scores = np.zeros((1, 1))
            indexs = np.zeros((1, 1))
            boxes = np.array([[0.0, 0.0, 2.0, 2.0]])
            classes = np.array([[0]])
            prob = np.zeros((1, 81))

    else:
        #@TODO
        raise "inference nms type error"

    batch_inds = np.zeros([boxes.shape[0]])

    return boxes.astype(np.float32), classes.astype(np.int32), prob.astype(
        np.float32), batch_inds.astype(np.int32), indexs.astype(np.int32)
예제 #9
0
def compute_detection_new(batch_rpn_box,
                          batch_rpn_prob,
                          batch_anchors,
                          image_inds,
                          ih,
                          iw,
                          num_classes,
                          score_threshold=0.5,
                          overlap_threshold=0.7,
                          only_anchor=False,
                          max_dets=100):
    """Post processing outputs of single shot detection, this decode boxes only once
    """
    assert image_inds.shape[0] == batch_rpn_box.shape[0] == batch_rpn_prob.shape[0] == batch_anchors.shape[0], \
        'unmatch output: {} vs {} vs {} vs {}'.format(image_inds.shape[0], batch_rpn_box.shape[0],
                                                      batch_rpn_prob.shape[0], batch_anchors.shape[0])

    n = cfg.batch_size
    rpn_box_ = batch_rpn_box.copy()
    if only_anchor:
        rpn_box_[...] = 0.0

    Dets = []
    for i in range(n):
        inds = np.where(image_inds == i)[0]
        bboxes = rpn_box_[inds]
        probs = batch_rpn_prob[inds]
        anc = batch_anchors[inds]

        probs_positive = 1 - probs[:,
                                   0]  # the objectness score = 1 - background
        final_boxes, _, _ = anchor.decode(bboxes, probs, anc, ih, iw,
                                          num_classes)

        object_dets = np.hstack(
            (final_boxes, probs_positive[:, np.newaxis])).astype(np.float32,
                                                                 copy=False)
        if False:
            keep, clusters = nms_multianchor(object_dets, overlap_threshold)
            keep = np.asarray(keep, dtype=np.int32)
            if only_anchor:
                object_dets = object_dets[keep, :]
            else:
                object_dets = dets_cluster(object_dets, keep, clusters)
        if True:
            keep = nms(object_dets, overlap_threshold)
            keep = np.asarray(keep, dtype=np.int32)
            object_dets = object_dets[keep, :]

        if keep.size > max_dets:
            keep = keep[:max_dets]

        probs = probs[keep]
        probs_objectness = probs[:, 1:]

        # if True:
        #     cls_dets = np.zeros([object_dets.shape[0], 6])
        #     cls_dets[:, 0:4] = object_dets[:, 0:4]
        #     cls_argmax = probs_objectness.argmax(axis=1)
        #     cls_maxprobs = probs_objectness[np.arange(cls_argmax.shape[0]), cls_argmax]
        #
        # else:
        d0, d1 = np.where(probs_objectness > score_threshold)
        cls_maxprobs = probs_objectness[d0, d1]
        cls_argmax = d1
        cls_dets = np.zeros([d0.size, 6])
        cls_dets[:, 0:4] = object_dets[d0, 0:4]

        cls_dets[:, 4] = cls_maxprobs
        cls_dets[:, 5] = cls_argmax + 1

        order = cls_dets[:, 4].argsort()[::-1]
        cls_dets = cls_dets[order, :]

        Dets.append(cls_dets)
    return Dets
예제 #10
0
def sample_rcnn_outputs(boxes, classes, prob, class_agnostic=False):
    min_size = cfg.FLAGS.min_size
    mask_nms_threshold = cfg.FLAGS.mask_nms_threshold
    post_nms_inst_n = cfg.FLAGS.post_nms_inst_n
    if class_agnostic is True:
        scores = prob.max(axis=1)

        boxes = boxes.reshape((-1, 4))
        classes = classes.reshape((-1, 1))
        scores = scores.reshape((-1, 1))
        probs = probs.reshape((-1, 81))

        assert scores.shape[0] == boxes.shape[0], 'scores and boxes dont match'

        # filter background
        keeps = np.where(classes != 0)[0]
        scores = scores[keeps]
        boxes = boxes[keeps, :]
        classes = classes[keeps]
        prob = prob[keeps, :]

        # filter minimum size
        keeps = _filter_boxes(boxes, min_size=min_size)
        scores = scores[keeps]
        boxes = boxes[keeps, :]
        classes = classes[keeps]
        prob = prob[keeps, :]

        #filter with scores
        keeps = np.where(scores > 0.5)[0]
        scores = scores[keeps]
        boxes = boxes[keeps, :]
        classes = classes[keeps]
        prob = prob[keeps, :]

        # filter with nms
        order = scores.ravel().argsort()[::-1]
        scores = scores[order]
        boxes = boxes[order, :]
        classes = classes[order]
        prob = prob[order, :]

        det = np.hstack((boxes, scores)).astype(np.float32)
        keeps = nms_wrapper.nms(det, mask_nms_threshold)

        scores = scores[keeps]
        boxes = boxes[keeps, :]
        classes = classes[keeps]
        prob = prob[keeps, :]

        # filter low score
        if post_nms_inst_n > 0:
            scores = scores[:post_nms_inst_n]
            boxes = boxes[:post_nms_inst_n, :]
            classes = classes[:post_nms_inst_n]
            prob = prob[:post_nms_inst_n, :]

        # quick fix for tensorflow error when no bbox presents
        #@TODO
        if len(classes) is 0:
            scores = np.zeros((1, 1))
            boxes = np.array([[0.0, 0.0, 2.0, 2.0]])
            classes = np.array([0]).reshape(-1)
            prob = np.zeros((1, 81))

    else:
        scores = prob.max(axis=1)

        boxes = boxes.reshape((-1, 4))
        classes = classes.reshape((-1, 1))
        scores = scores.reshape((-1, 1))
        prob = prob.reshape((-1, 81))
        assert scores.shape[0] == boxes.shape[0], 'scores and boxes dont match'

        # filter background
        keeps = np.where(classes != 0)[0]
        scores = scores[keeps]
        boxes = boxes[keeps, :]
        classes = classes[keeps]
        prob = prob[keeps, :]

        # filter minimum size
        keeps = _filter_boxes(boxes, min_size=min_size)
        scores = scores[keeps]
        boxes = boxes[keeps, :]
        classes = classes[keeps]
        prob = prob[keeps, :]

        #filter with scores
        keeps = np.where(scores > 0.5)[0]
        scores = scores[keeps]
        boxes = boxes[keeps, :]
        classes = classes[keeps]
        prob = prob[keeps, :]

        all_scores = []
        all_boxes = []
        all_classes = []
        all_prob = []

        for c in range(1, (prob.shape[1])):
            keeps = (classes == c).reshape(-1)

            per_class_scores = scores[keeps]
            per_class_boxes = boxes[keeps, :]
            per_class_classes = classes[keeps]
            per_class_prob = prob[keeps, :]

            # filter with nms
            order = per_class_scores.ravel().argsort()[::-1]
            per_class_scores = per_class_scores[order]
            per_class_boxes = per_class_boxes[order, :]
            per_class_classes = per_class_classes[order]
            per_class_prob = per_class_prob[order, :]

            det = np.hstack(
                (per_class_boxes, per_class_scores)).astype(np.float32)
            keeps = nms_wrapper.nms(det, mask_nms_threshold)

            # filter low score
            if post_nms_inst_n > 0:
                keeps = keeps[:post_nms_inst_n]
            all_scores.append(per_class_scores[keeps])
            all_boxes.append(per_class_boxes[keeps, :])
            all_classes.append(per_class_classes[keeps])
            all_prob.append(per_class_prob[keeps, :])

        scores = np.vstack(all_scores)
        boxes = np.vstack(all_boxes)
        classes = np.vstack(all_classes).reshape(-1)
        prob = np.vstack(all_prob)

        if len(classes) is 0:
            scores = np.zeros((1, 1))
            boxes = np.array([[0.0, 0.0, 2.0, 2.0]])
            classes = np.array([0]).reshape(-1)
            prob = np.zeros((1, 81))

    batch_inds = np.zeros([boxes.shape[0]])

    return boxes.astype(np.float32), classes.astype(np.int32), prob.astype(
        np.float32), batch_inds.astype(np.int32)
예제 #11
0
def sample_rpn_outputs(boxes,
                       scores,
                       is_training=False,
                       only_positive=False,
                       with_nms=False,
                       random=False):
    """Sample boxes according to scores and some learning strategies
  assuming the first class is background
  Params:
  boxes: of shape (..., Ax4), each entry is [x1, y1, x2, y2], the last axis has k*4 dims
  scores: of shape (..., A), probs of fg, in [0, 1]
  """
    min_size = cfg.FLAGS.min_size
    rpn_nms_threshold = cfg.FLAGS.rpn_nms_threshold
    pre_nms_top_n = cfg.FLAGS.pre_nms_top_n
    post_nms_top_n = cfg.FLAGS.post_nms_top_n

    # training: 12000, 2000
    # testing: 6000, 400
    # if not is_training:
    #   pre_nms_top_n = int(pre_nms_top_n / 2)
    #   post_nms_top_n = int(post_nms_top_n / 5)

    boxes = boxes.reshape((-1, 4))
    scores = scores.reshape((-1, 1))
    assert scores.shape[0] == boxes.shape[0], 'scores and boxes dont match'

    ## filter backgrounds
    ## Hope this will filter most of background anchors, since a argsort is too slow..
    if only_positive:
        keeps = np.where(scores > 0.5)[0]
        boxes = boxes[keeps, :]
        scores = scores[keeps]

    ## filter minimum size
    keeps = _filter_boxes(boxes, min_size=min_size)
    boxes = boxes[keeps, :]
    scores = scores[keeps]

    ## filter before nms
    if random is True:
        keeps = np.random.choice(np.arange(boxes.shape[0]),
                                 size=pre_nms_top_n,
                                 replace=False)
        boxes = boxes[keeps, :]
        scores = scores[keeps]
    else:
        if len(scores) > pre_nms_top_n:
            partial_order = scores.ravel()
            partial_order = np.argpartition(-partial_order,
                                            pre_nms_top_n)[:pre_nms_top_n]

            boxes = boxes[partial_order, :]
            scores = scores[partial_order]

    ## sort
    order = scores.ravel().argsort()[::-1]
    boxes = boxes[order, :]
    scores = scores[order]

    ## filter by nms
    if with_nms is True:
        det = np.hstack((boxes, scores)).astype(np.float32)
        keeps = nms_wrapper.nms(det, rpn_nms_threshold)
        boxes = boxes[keeps, :]
        scores = scores[keeps].astype(np.float32)

    ## filter after nms
    if post_nms_top_n > 0:
        boxes = boxes[:post_nms_top_n, :]
        scores = scores[:post_nms_top_n]

    #create dummpy box in case of no box remains
    if boxes.size is 0:
        boxes = np.array([[0, 0, 16, 16]], dtype=np.float32)
        scores = np.array([
            0,
        ], dtype=np.float32)

    batch_inds = np.zeros([boxes.shape[0]], dtype=np.int32)

    ## random sample boxes
    ## try early sample later
    # fg_inds = np.where(scores > 0.5)[0]
    # num_fgs = min(len(fg_inds.size), int(rois_per_image * fg_roi_fraction))

    # if _DEBUG:
    #   LOG('SAMPLE: %d rois has been choosen' % len(scores))
    #   LOG('SAMPLE: a positive box: %d %d %d %d %.4f' % (boxes[0, 0], boxes[0, 1], boxes[0, 2], boxes[0, 3], scores[0]))
    #   LOG('SAMPLE: a negative box: %d %d %d %d %.4f' % (boxes[-1, 0], boxes[-1, 1], boxes[-1, 2], boxes[-1, 3], scores[-1]))
    #   hs = boxes[:, 3] - boxes[:, 1]
    #   ws = boxes[:, 2] - boxes[:, 0]
    #   assert min(np.min(hs), np.min(ws)) > 0, 'invalid boxes'
    # print(boxes.shape)
    return boxes, scores, batch_inds