text: # --------------------------------------------------------
  # Tensorflow Faster R-CNN
  # Licensed under The MIT License [see LICENSE for details]
  # Written by Jiasen Lu, Jianwei Yang, based on code from Ross Girshick
  # --------------------------------------------------------
  from __future__ import absolute_import
  from __future__ import division
  from __future__ import print_function
  
  import _init_paths
  import os
  import sys
  import numpy as np
  import argparse
  import pprint
  import time
  import cv2
  import torch
  from torch.autograd import Variable
  import pickle
  from lib.roi_data_layer.roidb import get_imdb
  from lib.roi_data_layer.roibatchLoader import TestLoader
  from lib.model.utils.config import cfg, cfg_from_file, cfg_from_list, get_output_dir
  from lib.model.rpn.bbox_transform import clip_boxes
  from lib.model.nms.nms_wrapper import nms
  from lib.model.rpn.bbox_transform import bbox_transform_inv_reg
  from lib.model.utils.net_utils import vis_detections
  from lib.model.faster_rcnn.vgg16 import vgg16
  from lib.model.faster_rcnn.resnet import resnet
  from lib.datasets.factory import adjust_args
  
  import pdb
  
  try:
      xrange  # Python 2
  except NameError:
      xrange = range  # Python 3
  
  
  def parse_args():
      """
      Parse input arguments
      """
      parser = argparse.ArgumentParser(description='Train a Fast R-CNN network')
      parser.add_argument('--dataset', dest='dataset',
                          help='training dataset',
                          default='pascal_voc', type=str)
      parser.add_argument('--cfg', dest='cfg_file',
                          help='optional config file',
                          default='cfgs/vgg16.yml', type=str)
      parser.add_argument('--net', dest='net',
                          help='vgg16, res50, res101, res152',
                          default='res101', type=str)
      parser.add_argument('--set', dest='set_cfgs',
                          help='set config keys', default=None,
                          nargs=argparse.REMAINDER)
      parser.add_argument('--cuda', dest='cuda',
                          help='whether use CUDA',
                          action='store_true')
      parser.add_argument('--ls', dest='large_scale',
                          help='whether use large imag scale',
                          action='store_true')
      parser.add_argument('--mGPUs', dest='mGPUs',
                          help='whether use multiple GPUs',
                          action='store_true')
      parser.add_argument('--cag', dest='class_agnostic',
                          help='whether perform class_agnostic bbox regression',
                          action='store_true')
      parser.add_argument('--parallel_type', dest='parallel_type',
                          help='which part of model to parallel, 0: all, 1: model before roi pooling',
                          default=0, type=int)
      parser.add_argument('--checksession', dest='checksession',
                          help='checksession to load model',
                          default=1, type=int)
      parser.add_argument('--checkepoch', dest='checkepoch',
                          help='checkepoch to load network',
                          default=1, type=int)
      parser.add_argument('--checkpoint', dest='checkpoint',
                          help='checkpoint to load network',
                          default=10021, type=int)
      parser.add_argument('--epoch', dest='epoch',
                          help='epoch to test',
                          default=20, type=int)
      parser.add_argument('--model', dest='model',
                          help='model to test',
                          default=None, type=str)
      parser.add_argument('--bs', dest='batch_size',
                          help='batch_size',
                          default=1, type=int)
      parser.add_argument('--vis', dest='vis',
                          help='visualization mode',
                          action='store_true')
      parser.add_argument('--tag', dest='tag',
                          help='tag of the model',
                          default='', type=str)
      parser.add_argument('--imdb', dest='imdb_name',
                        help='dataset to train on',
                        default='voc_2007_trainval', type=str)
      parser.add_argument('--imdbval', dest='imdbval_name',
                        help='dataset to validate on',
                        default='voc_2007_test', type=str)
      args = parser.parse_args()
      return args
  
  
  lr = cfg.TRAIN.LEARNING_RATE
  momentum = cfg.TRAIN.MOMENTUM
  weight_decay = cfg.TRAIN.WEIGHT_DECAY
  
  if __name__ == '__main__':
  
      args = parse_args()
  
      if torch.cuda.is_available() and not args.cuda:
          print("WARNING: You have a CUDA device, so you should probably run with --cuda")
  
      np.random.seed(cfg.RNG_SEED)
      adjust_args(args)
  
      print('Called with args:')
      print(args)
  
      if args.cfg_file is not None:
          cfg_from_file(args.cfg_file)
      if args.set_cfgs is not None:
          cfg_from_list(args.set_cfgs)
  
      print('Using config:')
      pprint.pprint(cfg)
  
      cfg.TRAIN.USE_FLIPPED = False
      imdb = get_imdb(args.imdbval_name)
      imdb.competition_mode(on=True)
  
      # input_dir = args.load_dir + "/" + args.net + "/" + args.dataset
      load_name = args.model
      if not os.path.exists(load_name):
          raise Exception('There is no input file for loading network from ' + load_name)
      # load_name = os.path.join(input_dir,
      #   'faster_rcnn_{}_{}_{}.pth'.format(args.checksession, args.checkepoch, args.checkpoint))
  
      # initilize the network here.
      if args.net == 'vgg16':
          fasterRCNN = vgg16(imdb.classes, pretrained=False, class_agnostic=args.class_agnostic)
      elif args.net == 'res101':
          fasterRCNN = resnet(imdb.classes, 101, pretrained=False, class_agnostic=args.class_agnostic)
      elif args.net == 'res50':
          fasterRCNN = resnet(imdb.classes, 50, pretrained=False, class_agnostic=args.class_agnostic)
      elif args.net == 'res152':
          fasterRCNN = resnet(imdb.classes, 152, pretrained=False, class_agnostic=args.class_agnostic)
      else:
          print("network is not defined")
          pdb.set_trace()
  
      fasterRCNN.create_architecture()
  
      print("load checkpoint %s" % (load_name))
      checkpoint = torch.load(load_name)
      fasterRCNN.load_state_dict(checkpoint['model'])
      if 'pooling_mode' in checkpoint.keys():
          cfg.POOLING_MODE = checkpoint['pooling_mode']
  
      print('load model successfully!')
      # initilize the tensor holder here.
      im_data = torch.FloatTensor(1)
      im_info = torch.FloatTensor(1)
      num_boxes = torch.LongTensor(1)
      gt_boxes = torch.FloatTensor(1)
  
      # ship to cuda
      if args.cuda:
          im_data = im_data.cuda()
          im_info = im_info.cuda()
          num_boxes = num_boxes.cuda()
          gt_boxes = gt_boxes.cuda()
  
      # make variable
      im_data = Variable(im_data, volatile=True)
      im_info = Variable(im_info, volatile=True)
      num_boxes = Variable(num_boxes, volatile=True)
      gt_boxes = Variable(gt_boxes, volatile=True)
  
      if args.cuda:
          cfg.CUDA = True
  
      if args.cuda:
          fasterRCNN.cuda()
  
      start = time.time()
      max_per_image = 100
  
      vis = args.vis
  
      if vis:
          thresh = 0.05
      else:
          thresh = 0.0
  
      save_name = 'faster_rcnn_epoch_{}'.format(args.epoch)
      num_images = len(imdb.image_index)
      all_boxes = [[[] for _ in xrange(num_images)]
                   for _ in xrange(imdb.num_classes)]
      tag = args.tag
      tag = tag if tag else 'default'
      output_dir = get_output_dir(imdb, tag + '/' + save_name)
      if not os.path.exists(output_dir):
          os.makedirs(output_dir)
      dataset = TestLoader(imdb)
      dataloader = torch.utils.data.DataLoader(dataset, batch_size=args.batch_size,
                                               shuffle=False, num_workers=0,
                                               pin_memory=True)
  
      data_iter = iter(dataloader)
  
      _t = {'im_detect': time.time(), 'misc': time.time()}
      det_file = os.path.join(output_dir, 'detections.pkl')
  
      fasterRCNN.eval()
      empty_array = np.transpose(np.array([[], [], [], [], []]), (1, 0))
      for i in range(num_images):
          data = next(data_iter)
          im_data.data.resize_(data[0].size()).copy_(data[0])
          im_info.data.resize_(data[1].size()).copy_(data[1])
          gt_boxes.data.resize_(data[2].size()).copy_(data[2])
          num_boxes.data.resize_(data[3].size()).copy_(data[3])
  
          det_tic = time.time()
          rois, cls_prob, bbox_pred, \
          rpn_loss_cls, rpn_loss_box, \
          RCNN_loss_cls, RCNN_loss_bbox, RCNN_loss_edge, \
          rois_label = fasterRCNN(im_data, im_info, gt_boxes, num_boxes)
  
          scores = cls_prob.data
          boxes = rois.data[:, :, 1:5]
  
          if cfg.TEST.BBOX_REG:
              # Apply bounding-box regression deltas
              box_deltas = bbox_pred.data
              if cfg.TRAIN.BBOX_NORMALIZE_TARGETS_PRECOMPUTED:
                  # Optionally normalize targets by a precomputed mean and stdev
                  if args.class_agnostic:
                      box_deltas = box_deltas.view(-1, 4) * torch.FloatTensor(cfg.TRAIN.BBOX_NORMALIZE_STDS_REG).cuda() \
                                   + torch.FloatTensor(cfg.TRAIN.BBOX_NORMALIZE_MEANS_REG).cuda()
                      box_deltas = box_deltas.view(1, -1, 4)
                  else:
                      box_deltas = box_deltas.view(-1, 5) * torch.FloatTensor(cfg.TRAIN.BBOX_NORMALIZE_STDS_REG).cuda() \
                                   + torch.FloatTensor(cfg.TRAIN.BBOX_NORMALIZE_MEANS_REG).cuda()
                      box_deltas = box_deltas.view(1, -1, 5 * len(imdb.classes))
  
              pred_boxes = bbox_transform_inv_reg(boxes, box_deltas, 1)
              pred_boxes = clip_boxes(pred_boxes, im_info.data, 1)
          else:
              # Simply repeat the boxes, once for each class
              pred_boxes = np.tile(boxes, (1, scores.shape[1]))
  
          pred_boxes /= data[1][0][2]
  
          scores = scores.squeeze()
          pred_boxes = pred_boxes.squeeze()
          det_toc = time.time()
          detect_time = det_toc - det_tic
          misc_tic = time.time()
          if vis:
              im = cv2.imread(imdb.image_path_at(i))
              im2show = np.copy(im)
          for j in xrange(1, imdb.num_classes):
              inds = torch.nonzero(scores[:, j] > thresh).view(-1)
              # if there is det
              if inds.numel() > 0:
                  cls_scores = scores[:, j][inds]
                  _, order = torch.sort(cls_scores, 0, True)
                  if args.class_agnostic:
                      cls_quads = pred_boxes[inds, :]
                  else:
                      cls_quads = pred_boxes[inds][:, j * 8:(j + 1) * 8]
                  x1, _ = torch.min(cls_quads[:,0::2], dim=1)
                  x2, _ = torch.max(cls_quads[:,0::2], dim=1)
                  y1, _ = torch.min(cls_quads[:,1::2], dim=1)
                  y2, _ = torch.max(cls_quads[:,1::2], dim=1)
                  cls_boxes = torch.cat((x1.view(-1, 1), y1.view(-1, 1), x2.view(-1, 1), y2.view(-1, 1)), dim=1)
                  cls_scores = cls_scores.view(-1, 1)
                  cls_dets = torch.cat((cls_quads, cls_scores), 1)
                  cls_dets = cls_dets[order]
                  cls_dets_box = torch.cat((cls_boxes, cls_scores), 1)
                  cls_dets_box = cls_dets_box[order]
  
                  keep = nms(cls_dets_box, cfg.TEST.NMS)
                  cls_dets = cls_dets[keep.view(-1).long()]
                  cls_dets_box = cls_dets_box[keep.view(-1).long()]
                  if vis:
                      im2show = vis_detections(im2show, imdb.classes[j], cls_dets.cpu().numpy(), 0.3)
                  all_boxes[j][i] = cls_dets.cpu().numpy()
              else:
                  all_boxes[j][i] = empty_array
  
          # Limit to max_per_image detections *over all classes*
          if max_per_image > 0:
              image_scores = np.hstack([all_boxes[j][i][:, -1]
                                        for j in xrange(1, imdb.num_classes)])
              if len(image_scores) > max_per_image:
                  image_thresh = np.sort(image_scores)[-max_per_image]
                  for j in xrange(1, imdb.num_classes):
                      keep = np.where(all_boxes[j][i][:, -1] >= image_thresh)[0]
                      all_boxes[j][i] = all_boxes[j][i][keep, :]
  
          misc_toc = time.time()
          nms_time = misc_toc - misc_tic
  
          sys.stdout.write('im_detect: {:d}/{:d} {:.3f}s {:.3f}s   \r' \
                           .format(i + 1, num_images, detect_time, nms_time))
          sys.stdout.flush()
  
          if vis:
              cv2.imwrite('result.png', im2show)
              pdb.set_trace()
              # cv2.imshow('test', im2show)
              # cv2.waitKey(0)
  
      with open(det_file, 'wb') as f:
          pickle.dump(all_boxes, f, pickle.HIGHEST_PROTOCOL)
      print('\nEvaluating detections')
      if 'voc' in imdb.name:
          imdb.evaluate_detections(all_boxes, output_dir)
      else:
          imdb.evaluate_detections(tag, args.epoch)
      end = time.time()
      print("test time: %0.4fs" % (end - start))
  