//  [python]
def sample_proposals(self,labels, ious,gt_index,neg_nr, pos_nr):
        nr = neg_nr + pos_nr
        r_indices = tf.range(0, tf.shape(labels)[0])
        keep_indices = tf.greater_equal(labels,0)
        labels = tf.boolean_mask(labels, keep_indices)
        ious = tf.boolean_mask(ious,keep_indices)
        gt_index = tf.boolean_mask(gt_index,keep_indices)
        r_indices = tf.boolean_mask(r_indices, keep_indices)
        total_neg_nr = tf.reduce_sum(tf.to_int32(tf.equal(labels, 0)))
        total_pos_nr = tf.shape(labels)[0] - total_neg_nr

        with tf.name_scope("SelectRCNBoxes"):
            def random_select(indices, size):
                with tf.name_scope("random_select"):
                    data_nr = tf.shape(indices)[0]
                    indexs = tf.range(data_nr)
                    indexs = wpad(indexs, [0, size - data_nr])
                    indexs = tf.random_shuffle(indexs)
                    indexs = tf.random_crop(indexs, [size])
                    indices = tf.gather(indices, indexs)
                    return indices

            def random_select_pos(p_gt_index,indices, size):
                '''
                正样本按所属的ground truth box选择，由于每个gtbox的检测难易程度不同，如果按iou采样可能造成某些容易的gtbox的样本过多，困难的gtbox的样本过少
                :param p_gt_index:
                :param indices:
                :param size:
                :return:
                '''
                if not self.cfg.MODEL.ROI_HEADS.BALANCED_POS_SAMPLE:
                    print("Use normal fastrcnn pos sampler.")
                    return random_select(indices,size)

                print("Use balanced fastrcnn pos sampler.")
                with tf.name_scope("random_select"):
                    indexs = tfop.his_random_select(data=p_gt_index,select_nr=size)
                    #indexs = tf.Print(indexs,["indexs",tf.shape(p_gt_index),indexs],summarize=100)
                    indices = tf.gather(indices, indexs)
                    return indices


            def random_select_neg(ious,indices, size):
                if not self.cfg.MODEL.ROI_HEADS.BALANCED_NEG_SAMPLE:
                    print("Use normal fastrcnn neg sampler.")
                    return random_select(indices,size)
                low_value = self.cfg.MODEL.ROI_HEADS.BALANCED_NEG_SAMPLE_LOW_VALUE
                print(f"Use balanced fastrcnn neg sampler, low value = {low_value}.")
                with tf.name_scope("random_select"):
                    indexs = tfop.his_random_select(his_nr=8,min=low_value,max=0.5,data=ious,select_nr=size)
                    indices = tf.gather(indices, indexs)
                    return indices


            # positive and negitave number satisfy the requement
            def selectRCNBoxesM0():
                with tf.name_scope("M0"):
                    n_mask = tf.equal(labels, 0)
                    p_mask = tf.logical_not(n_mask)
                    n_indices = tf.boolean_mask(r_indices, n_mask)
                    n_ious = tf.boolean_mask(ious,n_mask)

                    p_gt_index = tf.boolean_mask(gt_index,p_mask)
                    p_indices = tf.boolean_mask(r_indices, p_mask)

                    p_indices = random_select_pos(p_gt_index,p_indices, pos_nr)
                    n_indices = random_select_neg(n_ious,n_indices, neg_nr)

                    return tf.concat([p_indices, n_indices], axis=0)

            # process the default situation
            def selectRCNBoxesM1():
                with tf.name_scope("M1"):
                    return random_select(r_indices, nr)

            # positive dosen't satisfy the requement
            def selectRCNBoxesM2():
                with tf.name_scope("M2"):
                    n_mask = tf.equal(labels, 0)
                    p_mask = tf.logical_not(n_mask)

                    n_indices = tf.boolean_mask(r_indices, n_mask)
                    n_ious = tf.boolean_mask(ious,n_mask)

                    p_indices = tf.boolean_mask(r_indices, p_mask)

                    with tf.name_scope("Select"):
                        n_indices = \
                            random_select_neg(n_ious, n_indices, nr - total_pos_nr)
                    return tf.concat([p_indices, n_indices], axis=0)

            # positive and negative is empty
            def selectRCNBoxesM3():
                with tf.name_scope("M3"):
                    # boxes = tf.constant([[0.0,0.0,0.001,0.001]],dtype=tf.float32)*tf.ones([nr,4],dtype=tf.float32)
                    # boxes_regs = tf.zeros_like(boxes,dtype=tf.float32)
                    return tf.zeros_like(labels)

            r_indices = tf.case({
                tf.logical_and(total_pos_nr >= pos_nr, total_neg_nr >= neg_nr): selectRCNBoxesM0,
                tf.logical_and(tf.logical_and(total_pos_nr < pos_nr, total_neg_nr >= neg_nr),
                               total_pos_nr > 0): selectRCNBoxesM2,
                tf.equal(tf.shape(labels)[0], 0): selectRCNBoxesM3
            },
                default=selectRCNBoxesM1,
                exclusive=True)

            r_indices.set_shape([nr])

            return r_indices