class_docstr: The mapper to preprocess the input data for training.
  
  Since the mapping may run in other processes, we write a new class and
  explicitly pass cfg to it, in the spirit of "explicitly pass resources to subprocess".
class_docstr_tok: ["The","mapper","to","preprocess","the","input","data","for","training",".","Since","the","mapping","may","run","in","other","processes",",","we","write","a","new","class","and","explicitly","pass","cfg","to","it",",","in","the","spirit","of","``","explicitly","pass","resources","to","subprocess","''","."]
docstr: Args:
      im: an image
      boxes: nx4, floatbox, gt. shoudn't be changed
      is_crowd: n,
  
  Returns:
      [(fm_labels, fm_boxes)]: Returns a tuple for each FPN level.
      Each tuple contains the anchor labels and target boxes for each pixel in the featuremap.
  
      fm_labels: fHxfWx NUM_ANCHOR_RATIOS
      fm_boxes: fHxfWx NUM_ANCHOR_RATIOS x4
docstr_tok: ["Args",":","im",":","an","image","boxes",":","nx4",",","floatbox",",","gt",".","shoud","n't","be","changed","is_crowd",":","n",",","Returns",":","[","(","fm_labels",",","fm_boxes",")","]",":","Returns","a","tuple","for","each","FPN","level",".","Each","tuple","contains","the","anchor","labels","and","target","boxes","for","each","pixel","in","the","featuremap",".","fm_labels",":","fHxfWx","NUM_ANCHOR_RATIOS","fm_boxes",":","fHxfWx","NUM_ANCHOR_RATIOS","x4"]
code: def get_multilevel_rpn_anchor_input(self, im, boxes, is_crowd):
      """
      Args:
          im: an image
          boxes: nx4, floatbox, gt. shoudn't be changed
          is_crowd: n,
  
      Returns:
          [(fm_labels, fm_boxes)]: Returns a tuple for each FPN level.
          Each tuple contains the anchor labels and target boxes for each pixel in the featuremap.
  
          fm_labels: fHxfWx NUM_ANCHOR_RATIOS
          fm_boxes: fHxfWx NUM_ANCHOR_RATIOS x4
      """
      boxes = boxes.copy()
      anchors_per_level = get_all_anchors_fpn(
          strides=self.cfg.FPN.ANCHOR_STRIDES,
          sizes=self.cfg.RPN.ANCHOR_SIZES,
          ratios=self.cfg.RPN.ANCHOR_RATIOS,
          max_size=self.cfg.PREPROC.MAX_SIZE,
      )
      flatten_anchors_per_level = [
          k.reshape((-1, 4)) for k in anchors_per_level
      ]
      all_anchors_flatten = np.concatenate(
          flatten_anchors_per_level, axis=0
      )
  
      inside_ind, inside_anchors = filter_boxes_inside_shape(
          all_anchors_flatten, im.shape[:2]
      )
  
      anchor_labels, anchor_gt_boxes = self.get_anchor_labels(
          inside_anchors, boxes[is_crowd == 0], boxes[is_crowd == 1]
      )
  
      # map back to all_anchors, then split to each level
      num_all_anchors = all_anchors_flatten.shape[0]
      all_labels = -np.ones((num_all_anchors,), dtype="int32")
      all_labels[inside_ind] = anchor_labels
      all_boxes = np.zeros((num_all_anchors, 4), dtype="float32")
      all_boxes[inside_ind] = anchor_gt_boxes
  
      start = 0
      multilevel_inputs = []
      for level_anchor in anchors_per_level:
          assert level_anchor.shape[2] == len(
              self.cfg.RPN.ANCHOR_RATIOS
          )
          anchor_shape = level_anchor.shape[
              :3
          ]  # fHxfWxNUM_ANCHOR_RATIOS
          num_anchor_this_level = np.prod(anchor_shape)
          end = start + num_anchor_this_level
          multilevel_inputs.append(
              (
                  all_labels[start:end].reshape(anchor_shape),
                  all_boxes[start:end, :].reshape(anchor_shape + (4,)),
              )
          )
          start = end
      assert end == num_all_anchors, "{} != {}".format(
          end, num_all_anchors
      )
      return multilevel_inputs
  
imports: import copy
  import itertools
  import numpy
  import cv2
  from tabulate import tabulate
  from termcolor import colored
  from tensorpack.dataflow import DataFromList, MapData, MapDataComponent, MultiProcessMapData, MultiThreadMapData, TestDataSpeed, imgaug
  from tensorpack.utils import logger
  from tensorpack.utils.argtools import log_once
  from modeling.model_rpn import get_all_anchors
  from modeling.model_fpn import get_all_anchors_fpn
  from common import CustomResize, DataFromListOfDict, box_to_point4, filter_boxes_inside_shape, np_iou, point4_to_box, polygons_to_mask
  from config import config
  from dataset import DatasetRegistry, register_coco
  from utils.np_box_ops import area
  from utils.np_box_ops import ioa
label_desc: Use image node_id 4 for calling the TrainingDataPreprocessor obj's underlying member method code with example usage: obj.get_multilevel_rpn_anchor_input(im, boxes, is_crowd) and returns: multilevel_inputs