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","''","."]
code: def __call__(self, roidb):
      fname, boxes, klass, is_crowd = (
          roidb["file_name"],
          roidb["boxes"],
          roidb["class"],
          roidb["is_crowd"],
      )
      assert boxes.ndim == 2 and boxes.shape[1] == 4, boxes.shape
      boxes = np.copy(boxes)
      im = cv2.imread(fname, cv2.IMREAD_COLOR)
      assert im is not None, fname
      im = im.astype("float32")
      height, width = im.shape[:2]
      # assume floatbox as input
      assert (
          boxes.dtype == np.float32
      ), "Loader has to return float32 boxes!"
  
      if not self.cfg.DATA.ABSOLUTE_COORD:
          boxes[:, 0::2] *= width
          boxes[:, 1::2] *= height
  
      # augmentation:
      tfms = self.aug.get_transform(im)
      im = tfms.apply_image(im)
      points = box_to_point4(boxes)
      points = tfms.apply_coords(points)
      boxes = point4_to_box(points)
      if len(boxes):
          assert (
              klass.max() <= self.cfg.DATA.NUM_CATEGORY
          ), "Invalid category {}!".format(klass.max())
          assert (
              np.min(np_area(boxes)) > 0
          ), "Some boxes have zero area!"
  
      ret = {"image": im}
      # Add rpn data to dataflow:
      try:
          if self.cfg.MODE_FPN:
              multilevel_anchor_inputs = (
                  self.get_multilevel_rpn_anchor_input(
                      im, boxes, is_crowd
                  )
              )
              for i, (anchor_labels, anchor_boxes) in enumerate(
                  multilevel_anchor_inputs
              ):
                  ret[
                      "anchor_labels_lvl{}".format(i + 2)
                  ] = anchor_labels
                  ret["anchor_boxes_lvl{}".format(i + 2)] = anchor_boxes
          else:
              (
                  ret["anchor_labels"],
                  ret["anchor_boxes"],
              ) = self.get_rpn_anchor_input(im, boxes, is_crowd)
  
          boxes = boxes[
              is_crowd == 0
          ]  # skip crowd boxes in training target
          klass = klass[is_crowd == 0]
          ret["gt_boxes"] = boxes
          ret["gt_labels"] = klass
      except MalformedData as e:
          log_once(
              "Input {} is filtered for training: {}".format(
                  fname, str(e)
              ),
              "warn",
          )
          return None
  
      if self.cfg.MODE_MASK:
          # augmentation will modify the polys in-place
          segmentation = copy.deepcopy(roidb["segmentation"])
          segmentation = [
              segmentation[k]
              for k in range(len(segmentation))
              if not is_crowd[k]
          ]
          assert len(segmentation) == len(boxes)
  
          # Apply augmentation on polygon coordinates.
          # And produce one image-sized binary mask per box.
          masks = []
          width_height = np.asarray([width, height], dtype=np.float32)
          gt_mask_width = int(
              np.ceil(im.shape[1] / 8.0) * 8
          )  # pad to 8 in order to pack mask into bits
  
          for polys in segmentation:
              if not self.cfg.DATA.ABSOLUTE_COORD:
                  polys = [p * width_height for p in polys]
              polys = [tfms.apply_coords(p) for p in polys]
              masks.append(
                  polygons_to_mask(polys, im.shape[0], gt_mask_width)
              )
  
          if len(masks):
              masks = np.asarray(
                  masks, dtype="uint8"
              )  # values in {0, 1}
              masks = np.packbits(masks, axis=-1)
          else:  # no gt on the image
              masks = np.zeros(
                  (0, im.shape[0], gt_mask_width // 8), dtype="uint8"
              )
  
          ret["gt_masks_packed"] = masks
  
          # from viz import draw_annotation, draw_mask
          # viz = draw_annotation(im, boxes, klass)
          # for mask in masks:
          #     viz = draw_mask(viz, mask)
          # tpviz.interactive_imshow(viz)
      return ret
  
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 2 for calling the TrainingDataPreprocessor obj's underlying member method code with example usage: obj.__call__(roidb) and returns: ret, None