text: # Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved.
  #
  # Licensed under the Apache License, Version 2.0 (the "License");
  # you may not use this file except in compliance with the License.
  # You may obtain a copy of the License at
  #
  #     http://www.apache.org/licenses/LICENSE-2.0
  #
  # Unless required by applicable law or agreed to in writing, software
  # distributed under the License is distributed on an "AS IS" BASIS,
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  # See the License for the specific language governing permissions and
  # limitations under the License.
  import logging
  import math
  import time
  
  import cv2
  import numpy as np
  import onnxruntime as ort
  
  from ppocronnx.utility import get_model_data, get_character_dict, get_model_data_from_path
  from .rec_decoder import CTCLabelDecode
  
  logger = logging
  character_dict = get_character_dict()
  rec_model_file = 'ch_PP-OCRv2_rec_infer.onnx'
  
  
  class TextRecognizer(object):
      def __init__(self, rec_model_path=None):
          self.rec_image_shape = [3, 32, 320]
          self.character_type = 'ch'
          self.rec_batch_num = 6
          self.rec_algorithm = 'CRNN'
          self.postprocess_op = CTCLabelDecode(character_dict=character_dict,
                                               character_type='ch', use_space_char=True)
          model_data = get_model_data(rec_model_file) if rec_model_path is None else get_model_data_from_path(rec_model_path)
          so = ort.SessionOptions()
          so.log_severity_level = 3
          sess = ort.InferenceSession(model_data, so)
          self.predictor, self.input_tensor = sess, sess.get_inputs()[0]
          self.output_tensors = None
  
      def resize_norm_img(self, img, max_wh_ratio):
          imgC, imgH, imgW = self.rec_image_shape
          assert imgC == img.shape[2]
          if self.character_type == "ch":
              imgW = int((32 * max_wh_ratio))
          h, w = img.shape[:2]
          ratio = w / float(h)
          if math.ceil(imgH * ratio) > imgW:
              resized_w = imgW
          else:
              resized_w = int(math.ceil(imgH * ratio))
          resized_image = cv2.resize(img, (resized_w, imgH))
          resized_image = resized_image.astype('float32')
          resized_image = resized_image.transpose((2, 0, 1)) / 255
          resized_image -= 0.5
          resized_image /= 0.5
          padding_im = np.zeros((imgC, imgH, imgW), dtype=np.float32)
          padding_im[:, :, 0:resized_w] = resized_image
          return padding_im
  
      def set_char_whitelist(self, chars):
          self.postprocess_op.set_char_mask(chars)
  
      def __call__(self, img_list):
          img_num = len(img_list)
          # Calculate the aspect ratio of all text bars
          width_list = []
          for img in img_list:
              width_list.append(img.shape[1] / float(img.shape[0]))
          # Sorting can speed up the recognition process
          indices = np.argsort(np.array(width_list))
  
          # rec_res = []
          rec_res = [['', 0.0]] * img_num
          batch_num = self.rec_batch_num
          elapse = 0
          for beg_img_no in range(0, img_num, batch_num):
              end_img_no = min(img_num, beg_img_no + batch_num)
              norm_img_batch = []
              max_wh_ratio = 0
              for ino in range(beg_img_no, end_img_no):
                  # h, w = img_list[ino].shape[0:2]
                  h, w = img_list[indices[ino]].shape[0:2]
                  wh_ratio = w * 1.0 / h
                  max_wh_ratio = max(max_wh_ratio, wh_ratio)
              for ino in range(beg_img_no, end_img_no):
                  # norm_img = self.resize_norm_img(img_list[ino], max_wh_ratio)
                  norm_img = self.resize_norm_img(img_list[indices[ino]],
                                                  max_wh_ratio)
                  norm_img = norm_img[np.newaxis, :]
                  norm_img_batch.append(norm_img)
              norm_img_batch = np.concatenate(norm_img_batch)
              norm_img_batch = norm_img_batch.copy()
              starttime = time.time()
              input_dict = {}
              input_dict[self.input_tensor.name] = norm_img_batch
              outputs = self.predictor.run(self.output_tensors, input_dict)
              preds = outputs[0]
              rec_result = self.postprocess_op(preds)
              for rno in range(len(rec_result)):
                  rec_res[indices[beg_img_no + rno]] = rec_result[rno]
              elapse += time.time() - starttime
          return rec_res, elapse
  