code: def test_proposals(predictor, test_data, imdb, roidb, vis=False):
      """
      Test detections results using RPN.
      :param predictor: Predictor
      :param test_data: data iterator, must be non-shuffled
      :param imdb: image database
      :param roidb: roidb
      :param vis: controls visualization
      :return: recall, mAP
      """
      assert vis or not test_data.shuffle
      data_names = [k[0] for k in test_data.provide_data]
  
      # bbox_file = os.path.join(rpn_folder, imdb.name + '_bbox.txt')
      # bbox_f = open(bbox_file, 'w')
  
      i = 0
      t = time.time()
      output_folder = os.path.join(imdb.root_path, "output")
      if not os.path.exists(output_folder):
          os.mkdir(output_folder)
      imdb_boxes = list()
      original_boxes = list()
      gt_overlaps = np.zeros(0)
      overall = [0.0, 0.0]
      gt_max = np.array((0.0, 0.0))
      num_pos = 0
      # apply scale, for SSH
      # _, roidb = image.get_image(roidb)
      for im_info, data_batch in test_data:
          t1 = time.time() - t
          t = time.time()
  
          oscale = im_info[0, 2]
          # print('scale', scale, file=sys.stderr)
          scale = 1.0  # fix scale=1.0 for SSH face detector
          scores, boxes, data_dict = im_proposal(
              predictor, data_batch, data_names, scale
          )
          # print(scores.shape, boxes.shape, file=sys.stderr)
          t2 = time.time() - t
          t = time.time()
  
          # assemble proposals
          dets = np.hstack((boxes, scores))
          original_boxes.append(dets)
  
          # filter proposals
          keep = np.where(dets[:, 4:] > config.TEST.SCORE_THRESH)[0]
          dets = dets[keep, :]
          imdb_boxes.append(dets)
  
          logger.info(
              "generating %d/%d " % (i + 1, imdb.num_images)
              + "proposal %d " % (dets.shape[0])
              + "data %.4fs net %.4fs" % (t1, t2)
          )
  
          # if dets.shape[0]==0:
          #  continue
          if vis:
              vis_all_detection(
                  data_dict["data"].asnumpy(), [dets], ["obj"], scale
              )
          boxes = dets
          # max_gt_overlaps = roidb[i]['gt_overlaps'].max(axis=1)
          # gt_inds = np.where((roidb[i]['gt_classes'] > 0) & (max_gt_overlaps == 1))[0]
          # gt_boxes = roidb[i]['boxes'][gt_inds, :]
          gt_boxes = (
              roidb[i]["boxes"].copy() * oscale
          )  # as roidb is the original one, need to scale GT for SSH
          gt_areas = (gt_boxes[:, 2] - gt_boxes[:, 0] + 1) * (
              gt_boxes[:, 3] - gt_boxes[:, 1] + 1
          )
          num_pos += gt_boxes.shape[0]
  
          overlaps = bbox_overlaps(
              boxes.astype(np.float), gt_boxes.astype(np.float)
          )
          # print(im_info, gt_boxes.shape, boxes.shape, overlaps.shape, file=sys.stderr)
  
          _gt_overlaps = np.zeros((gt_boxes.shape[0]))
          # choose whatever is smaller to iterate
  
          # for j in range(gt_boxes.shape[0]):
          #  print('gt %d,%d,%d,%d'% (gt_boxes[j][0], gt_boxes[j][1], gt_boxes[j][2]-gt_boxes[j][0], gt_boxes[j][3]-gt_boxes[j][1]), file=sys.stderr)
          #  gt_max = np.maximum( gt_max, np.array( (gt_boxes[j][2], gt_boxes[j][3]) ) )
          # print('gt max', gt_max, file=sys.stderr)
          # for j in range(boxes.shape[0]):
          #  print('anchor_box %.2f,%.2f,%.2f,%.2f'% (boxes[j][0], boxes[j][1], boxes[j][2]-boxes[j][0], boxes[j][3]-boxes[j][1]), file=sys.stderr)
  
          # rounds = min(boxes.shape[0], gt_boxes.shape[0])
          # for j in range(rounds):
          #    # find which proposal maximally covers each gt box
          #    argmax_overlaps = overlaps.argmax(axis=0)
          #    print(j, 'argmax_overlaps', argmax_overlaps, file=sys.stderr)
          #    # get the IoU amount of coverage for each gt box
          #    max_overlaps = overlaps.max(axis=0)
          #    print(j, 'max_overlaps', max_overlaps, file=sys.stderr)
          #    # find which gt box is covered by most IoU
          #    gt_ind = max_overlaps.argmax()
          #    gt_ovr = max_overlaps.max()
          #    assert (gt_ovr >= 0), '%s\n%s\n%s' % (boxes, gt_boxes, overlaps)
          #    # find the proposal box that covers the best covered gt box
          #    box_ind = argmax_overlaps[gt_ind]
          #    print('max box', gt_ind, box_ind, (boxes[box_ind][0], boxes[box_ind][1], boxes[box_ind][2]-boxes[box_ind][0], boxes[box_ind][3]-boxes[box_ind][1], boxes[box_ind][4]), file=sys.stderr)
          #    # record the IoU coverage of this gt box
          #    _gt_overlaps[j] = overlaps[box_ind, gt_ind]
          #    assert (_gt_overlaps[j] == gt_ovr)
          #    # mark the proposal box and the gt box as used
          #    overlaps[box_ind, :] = -1
          #    overlaps[:, gt_ind] = -1
  
          if boxes.shape[0] > 0:
              _gt_overlaps = overlaps.max(axis=0)
              # print('max_overlaps', _gt_overlaps, file=sys.stderr)
              for j in range(len(_gt_overlaps)):
                  if _gt_overlaps[j] > config.TEST.IOU_THRESH:
                      continue
                  print(
                      j,
                      "failed",
                      gt_boxes[j],
                      "max_overlap:",
                      _gt_overlaps[j],
                      file=sys.stderr,
                  )
                  # _idx = np.where(overlaps[:,j]>0.4)[0]
                  # print(j, _idx, file=sys.stderr)
                  # print(overlaps[_idx,j], file=sys.stderr)
                  # for __idx in _idx:
                  #  print(gt_boxes[j], boxes[__idx], overlaps[__idx,j], IOU(gt_boxes[j], boxes[__idx,0:4]), file=sys.stderr)
  
              # append recorded IoU coverage level
              found = (_gt_overlaps > config.TEST.IOU_THRESH).sum()
              _recall = found / float(gt_boxes.shape[0])
              print(
                  "recall",
                  _recall,
                  gt_boxes.shape[0],
                  boxes.shape[0],
                  gt_areas,
                  file=sys.stderr,
              )
              overall[0] += found
              overall[1] += gt_boxes.shape[0]
              # gt_overlaps = np.hstack((gt_overlaps, _gt_overlaps))
              # _recall = (gt_overlaps >= threshold).sum() / float(num_pos)
              _recall = float(overall[0]) / overall[1]
              print("recall_all", _recall, file=sys.stderr)
  
          boxes[:, 0:4] /= oscale
          _vec = roidb[i]["image"].split("/")
          out_dir = os.path.join(output_folder, _vec[-2])
          if not os.path.exists(out_dir):
              os.mkdir(out_dir)
          out_file = os.path.join(
              out_dir, _vec[-1].replace("jpg", "txt")
          )
          with open(out_file, "w") as f:
              name = "/".join(roidb[i]["image"].split("/")[-2:])
              f.write("%s\n" % (name))
              f.write("%d\n" % (boxes.shape[0]))
              for b in range(boxes.shape[0]):
                  box = boxes[b]
                  f.write(
                      "%d %d %d %d %g \n"
                      % (
                          box[0],
                          box[1],
                          box[2] - box[0],
                          box[3] - box[1],
                          box[4],
                      )
                  )
          i += 1
  
      # bbox_f.close()
      return
      gt_overlaps = np.sort(gt_overlaps)
      recalls = np.zeros_like(thresholds)
  
      # compute recall for each IoU threshold
      for i, t in enumerate(thresholds):
          recalls[i] = (gt_overlaps >= t).sum() / float(num_pos)
      ar = recalls.mean()
  
      # print results
      print("average recall for {}: {:.3f}".format(area_name, ar))
      for threshold, recall in zip(thresholds, recalls):
          print("recall @{:.2f}: {:.3f}".format(threshold, recall))
  
      assert (
          len(imdb_boxes) == imdb.num_images
      ), "calculations not complete"
  
      # save results
  
      rpn_file = os.path.join(rpn_folder, imdb.name + "_rpn.pkl")
      with open(rpn_file, "wb") as f:
          pickle.dump(imdb_boxes, f, pickle.HIGHEST_PROTOCOL)
  
      logger.info("wrote rpn proposals to %s" % rpn_file)
      return imdb_boxes
  
imports: from __future__ import print_function
  import os
  import sys
  import time
  import mxnet
  import numpy
  from builtins import range
  from mxnet.module import Module
  from .module import MutableModule
  from rcnn.logger import logger
  from rcnn.config import config
  from rcnn.io import image
  from rcnn.processing.bbox_transform import bbox_pred, clip_boxes
  from rcnn.processing.nms import py_nms_wrapper, cpu_nms_wrapper, gpu_nms_wrapper
  from rcnn.processing.bbox_transform import bbox_overlaps
label_desc: Use image node_id 5 for calling a global function with example usage: test_proposals(predictor, test_data, imdb, roidb, vis) and returns: imdb_boxes