text: #!/usr/bin/env python
  # -*- coding: utf-8 -*-
  import argparse
  import itertools
  import numpy as np
  import os
  import shutil
  import tensorflow as tf
  import cv2
  import six
  import tqdm
  
  assert six.PY3, "This example requires Python 3!"
  
  import tensorpack.utils.viz as tpviz
  from tensorpack.predict import MultiTowerOfflinePredictor, OfflinePredictor, PredictConfig
  from tensorpack.tfutils import SmartInit, get_tf_version_tuple
  from tensorpack.tfutils.export import ModelExporter
  from tensorpack.utils import fs, logger
  
  from mot.object_detection.dataset import DatasetRegistry, register_mot
  from mot.object_detection.config import config as cfg
  from mot.object_detection.config import finalize_configs
  from mot.object_detection.data import get_eval_dataflow, get_train_dataflow
  from mot.object_detection.eval import DetectionResult, multithread_predict_dataflow, predict_image
  from mot.object_detection.modeling.generalized_rcnn import ResNetC4Model, ResNetFPNModel
  from mot.object_detection.viz import (
      draw_annotation, draw_final_outputs, draw_predictions,
      draw_proposal_recall, draw_final_outputs_blackwhite)
  
  
  def do_visualize(model, model_path, nr_visualize=100, output_dir='output'):
      """
      Visualize some intermediate results (proposals, raw predictions) inside the pipeline.
      """
      df = get_train_dataflow()
      df.reset_state()
  
      pred = OfflinePredictor(PredictConfig(
          model=model,
          session_init=SmartInit(model_path),
          input_names=['image', 'gt_boxes', 'gt_labels'],
          output_names=[
              'generate_{}_proposals/boxes'.format('fpn' if cfg.MODE_FPN else 'rpn'),
              'generate_{}_proposals/scores'.format('fpn' if cfg.MODE_FPN else 'rpn'),
              'fastrcnn_all_scores',
              'output/boxes',
              'output/scores',
              'output/labels',
          ]))
  
      if os.path.isdir(output_dir):
          shutil.rmtree(output_dir)
      fs.mkdir_p(output_dir)
      with tqdm.tqdm(total=nr_visualize) as pbar:
          for idx, dp in itertools.islice(enumerate(df), nr_visualize):
              img, gt_boxes, gt_labels = dp['image'], dp['gt_boxes'], dp['gt_labels']
  
              rpn_boxes, rpn_scores, all_scores, \
                  final_boxes, final_scores, final_labels = pred(img, gt_boxes, gt_labels)
  
              # draw groundtruth boxes
              gt_viz = draw_annotation(img, gt_boxes, gt_labels)
              # draw best proposals for each groundtruth, to show recall
              proposal_viz, good_proposals_ind = draw_proposal_recall(img, rpn_boxes, rpn_scores, gt_boxes)
              # draw the scores for the above proposals
              score_viz = draw_predictions(img, rpn_boxes[good_proposals_ind], all_scores[good_proposals_ind])
  
              results = [DetectionResult(*args) for args in
                         zip(final_boxes, final_scores, final_labels,
                             [None] * len(final_labels))]
              final_viz = draw_final_outputs(img, results)
  
              viz = tpviz.stack_patches([
                  gt_viz, proposal_viz,
                  score_viz, final_viz], 2, 2)
  
              if os.environ.get('DISPLAY', None):
                  tpviz.interactive_imshow(viz)
              cv2.imwrite("{}/{:03d}.png".format(output_dir, idx), viz)
              pbar.update()
  
  
  def do_evaluate(pred_config, output_file):
      num_tower = max(cfg.TRAIN.NUM_GPUS, 1)
      graph_funcs = MultiTowerOfflinePredictor(
          pred_config, list(range(num_tower))).get_predictors()
  
      for dataset in cfg.DATA.VAL:
          logger.info("Evaluating {} ...".format(dataset))
          dataflows = [
              get_eval_dataflow(dataset, shard=k, num_shards=num_tower)
              for k in range(num_tower)]
          all_results = multithread_predict_dataflow(dataflows, graph_funcs)
          output = output_file + '-' + dataset
          DatasetRegistry.get(dataset).eval_inference_results(all_results, output)
  
  
  def do_predict(pred_func, input_file, visualize=False):
      img = cv2.imread(input_file, cv2.IMREAD_COLOR)
      if not visualize:
          return predict_image(img, pred_func)
      results = predict_image(img, pred_func, as_named_tuple=True)
      if cfg.MODE_MASK:
          final = draw_final_outputs_blackwhite(img, results)
      else:
          final = draw_final_outputs(img, results)
      viz = np.concatenate((img, final), axis=1)
      cv2.imwrite("output.png", viz)
      logger.info("Inference output for {} written to output.png".format(input_file))
      tpviz.interactive_imshow(viz)
  
  
  if __name__ == '__main__':
      parser = argparse.ArgumentParser()
      parser.add_argument('--load', help='load a model for evaluation.', required=True)
      parser.add_argument('--visualize', action='store_true', help='visualize intermediate results')
      parser.add_argument('--evaluate', help="Run evaluation. "
                                             "This argument is the path to the output json evaluation file")
      parser.add_argument('--predict', help="Run prediction on a given image. "
                                            "This argument is the path to the input image file", nargs='+')
      parser.add_argument('--benchmark', action='store_true', help="Benchmark the speed of the model + postprocessing")
      parser.add_argument('--config', help="A list of KEY=VALUE to overwrite those defined in config.py",
                          nargs='+')
      parser.add_argument('--compact', help='Save a model to .pb')
      parser.add_argument('--serving', help='Save a model to serving file')
  
      args = parser.parse_args()
      if args.config:
          cfg.update_args(args.config)
      register_mot(cfg.DATA.BASEDIR) # add the mot datasets to the registry
  
      MODEL = ResNetFPNModel() if cfg.MODE_FPN else ResNetC4Model()
  
      if not tf.test.is_gpu_available():
          from tensorflow.python.framework import test_util
          assert get_tf_version_tuple() >= (1, 7) and test_util.IsMklEnabled(), \
              "Inference requires either GPU support or MKL support!"
      assert args.load
      finalize_configs(is_training=False)
  
      if args.predict or args.visualize:
          cfg.TEST.RESULT_SCORE_THRESH = cfg.TEST.RESULT_SCORE_THRESH_VIS
  
      if args.visualize:
          do_visualize(MODEL, args.load)
      else:
          predcfg = PredictConfig(
              model=MODEL,
              session_init=SmartInit(args.load),
              input_names=MODEL.get_inference_tensor_names()[0],
              output_names=MODEL.get_inference_tensor_names()[1])
  
          if args.compact:
              ModelExporter(predcfg).export_compact(args.compact)
          elif args.serving:
              ModelExporter(predcfg).export_serving(args.serving, signature_name="serving_default")
  
          if args.predict:
              predictor = OfflinePredictor(predcfg)
              for image_file in args.predict:
                  do_predict(predictor, image_file, visualize=True)
          elif args.evaluate:
              assert args.evaluate.endswith('.json'), args.evaluate
              do_evaluate(predcfg, args.evaluate)
          elif args.benchmark:
              df = get_eval_dataflow(cfg.DATA.VAL[0])
              df.reset_state()
              predictor = OfflinePredictor(predcfg)
              for _, img in enumerate(tqdm.tqdm(df, total=len(df), smoothing=0.5)):
                  # This includes post-processing time, which is done on CPU and not optimized
                  # To exclude it, modify `predict_image`.
                  predict_image(img[0], predictor)
  