text: # --------------------------------------------------------
  # Tensorflow SSH
  # Licensed under The MIT License [see LICENSE for details]
  # Modify by Jinchang Wan
  # --------------------------------------------------------
  from __future__ import absolute_import
  from __future__ import division
  from __future__ import print_function
  
  import cv2
  import numpy as np
  
  try:
      import cPickle as pickle
  except ImportError:
      import pickle
  import os
  import math
  
  from utils.timer import Timer
  from utils.blob import im_list_to_blob
  
  from model.config import cfg, get_output_dir
  from model.bbox_transform import clip_boxes, bbox_transform_inv
  from model.nms_wrapper import nms
  
  
  def _get_image_blob(im):
      """Converts an image into a network input.
      Arguments:
        im (ndarray): a color image in BGR order
      Returns:
        blob (ndarray): a data blob holding an image pyramid
        im_scale_factors (list): list of image scales (relative to im) used
          in the image pyramid
      """
      im_orig = im.astype(np.float32, copy=True)
      im_orig -= cfg.PIXEL_MEANS
  
      im_shape = im_orig.shape
      im_size_min = np.min(im_shape[0:2])
      im_size_max = np.max(im_shape[0:2])
  
      processed_ims = []
      im_scale_factors = []
  
      for target_size in cfg.TEST.SCALES:
          im_scale = float(target_size) / float(im_size_min)
          # Prevent the biggest axis from being more than MAX_SIZE
          if np.round(im_scale * im_size_max) > cfg.TEST.MAX_SIZE:
              im_scale = float(cfg.TEST.MAX_SIZE) / float(im_size_max)
          im = cv2.resize(im_orig, None, None, fx=im_scale, fy=im_scale,
                          interpolation=cv2.INTER_LINEAR)
          im_scale_factors.append(im_scale)
          processed_ims.append(im)
  
      # Create a blob to hold the input images
      blob = im_list_to_blob(processed_ims)
  
      return blob, np.array(im_scale_factors)
  
  def _get_image_blobs(im):
      """Converts an image into a network input for faster version.
          Arguments:
            im (ndarray): a color image in BGR order
          Returns:
            blob (ndarray): a data blob holding an image pyramid
            im_scale_factors (list): list of image scales (relative to im) used
              in the image pyramid
      """
      im_orig = im.astype(np.float32, copy=True)
      im_scale_factors = []
      h, w = im.shape[:2]
      im_size_min = np.min(im.shape[0:2])
      im_size_max = np.max(im.shape[0:2])
      im_scale = float(cfg.TEST.SCALES[0]) / float(im_size_min)
      if np.round(im_scale * im_size_max) > cfg.TEST.MAX_SIZE:
          im_scale = float(cfg.TEST.MAX_SIZE) / float(im_size_max)
      im_scale_factors.append(im_scale)
      target_size = (int(im_scale * w), int(im_scale * h))
      im = cv2.resize(im_orig, target_size)
      im -= cfg.PIXEL_MEANS
  
      # Create a blob to hold the input images
      blob = im[np.newaxis, :, :, :]
  
      return blob, np.array(im_scale_factors)
  
  def _get_blobs(im):
      """Convert an image and RoIs within that image into network inputs."""
      blobs = {}
      blobs['data'], im_scale_factors = _get_image_blobs(im)
  
      return blobs, im_scale_factors
  
  
  def _clip_boxes(boxes, im_shape):
      """Clip boxes to image boundaries."""
      # x1 >= 0
      boxes[:, 0::4] = np.maximum(boxes[:, 0::4], 0)
      # y1 >= 0
      boxes[:, 1::4] = np.maximum(boxes[:, 1::4], 0)
      # x2 < im_shape[1]
      boxes[:, 2::4] = np.minimum(boxes[:, 2::4], im_shape[1] - 1)
      # y2 < im_shape[0]
      boxes[:, 3::4] = np.minimum(boxes[:, 3::4], im_shape[0] - 1)
      return boxes
  
  
  def _rescale_boxes(boxes, inds, scales):
      """Rescale boxes according to image rescaling."""
      for i in range(boxes.shape[0]):
          boxes[i, :] = boxes[i, :] / scales[int(inds[i])]
  
      return boxes
  
  
  def im_detect(sess, net, im):
      blobs, im_scales = _get_blobs(im)  
      assert len(im_scales) == 1, "Only single-image batch implemented"
  
      im_blob = blobs['data']
      blobs['im_info'] = np.array([im_blob.shape[1], im_blob.shape[2], im_scales[0]], dtype=np.float32)
  
      scores, rois = net.test_image(sess, blobs['data'], blobs['im_info'])
      boxes = rois[:, 1:5] / im_scales[0]
      scores = np.reshape(scores, [scores.shape[0], -1])
      pred_boxes = np.tile(boxes, (1, scores.shape[1]))
  
      return scores, pred_boxes
  
  
  def apply_nms(all_boxes, thresh):
      """Apply non-maximum suppression to all predicted boxes output by the
      test_net method.
      """
      num_classes = len(all_boxes)
      num_images = len(all_boxes[0])
      nms_boxes = [[[] for _ in range(num_images)] for _ in range(num_classes)]
      for cls_ind in range(num_classes):
          for im_ind in range(num_images):
              dets = all_boxes[cls_ind][im_ind]
              if dets == []:
                  continue
  
              x1 = dets[:, 0]
              y1 = dets[:, 1]
              x2 = dets[:, 2]
              y2 = dets[:, 3]
              scores = dets[:, 4]
              inds = np.where((x2 > x1) & (y2 > y1))[0]
              dets = dets[inds, :]
              if dets == []:
                  continue
  
              keep = nms(dets, thresh)
              if len(keep) == 0:
                  continue
              nms_boxes[cls_ind][im_ind] = dets[keep, :].copy()
      return nms_boxes
  
  
  def test_net(sess, net, imdb, weights_filename, thresh=0.05):
      np.random.seed(cfg.RNG_SEED)
      """Test a SSH network on an image database."""
      num_images = len(imdb.image_index)
      # all detections are collected into:
      #  all_boxes[cls][image] = N x 5 array of detections in
      #  (x1, y1, x2, y2, score)
      all_boxes = [[] for _ in range(num_images)]
  
      output_dir = get_output_dir(imdb, weights_filename)
      # timers
      _t = {'im_detect': Timer(), 'misc': Timer()}
  
      for i in range(num_images):
          im = cv2.imread(imdb.image_path_at(i))
  
          _t['im_detect'].tic()
          scores, boxes = im_detect(sess, net, im)
          _t['im_detect'].toc()
  
          _t['misc'].tic()
  
          inds = np.where(scores[:, 0] > thresh)[0]
          scores = scores[inds, 0]
          boxes = boxes[inds, :]
          dets = np.hstack((boxes, scores[:, np.newaxis])).astype(np.float32, copy=False)
          keep = nms(dets, cfg.TEST.NMS)
          dets = dets[keep, :]
          all_boxes[i] = det
          _t['misc'].toc()
  
          print('im_detect: {:d}/{:d} {:.3f}s {:.3f}s' \
                .format(i + 1, num_images, _t['im_detect'].average_time,
                        _t['misc'].average_time))
  
      det_file = os.path.join(output_dir, 'detections.pkl')
      with open(det_file, 'wb') as f:
          pickle.dump(all_boxes, f, pickle.HIGHEST_PROTOCOL)
  
      print('Evaluating detections')
      imdb.evaluate_detections(all_boxes, output_dir)
  