penguin_ocr.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. # @Author : lightXu
  2. # @File : penguin_ocr.py
  3. # @Time : 2019/6/11 0011 下午 17:52
  4. import base64
  5. import hashlib
  6. import random
  7. import string
  8. import time
  9. from urllib.parse import urlencode
  10. import cv2
  11. import requests
  12. from requests.adapters import HTTPAdapter
  13. from urllib3.util.retry import Retry
  14. from segment.image_operation.utils import resize_by_percent, write_single_img
  15. APP_KEY = 'R2iPkd5J2056YFRw'
  16. APP_ID = '2117302084'
  17. def opecv2base64(img):
  18. image = cv2.imencode('.jpg', img)[1]
  19. base64_data = str(base64.b64encode(image))[2:-1]
  20. return base64_data
  21. def get_base64_size(base64_str):
  22. length = len(base64_str)
  23. size = float(length - 2 * length/8) # byte
  24. return size
  25. def opecv2base64_stand(raw_image, mem_size, default_size=1): # 小于1M
  26. default_size = default_size * 1000 * 1000
  27. m_ratio = mem_size/default_size
  28. if m_ratio > 1.0:
  29. y, x = raw_image.shape[0], raw_image.shape[1]
  30. s_ratio = max(y, x) / 1200
  31. ratio = max(m_ratio, s_ratio)
  32. image_resize = resize_by_percent(raw_image, 1/ratio)
  33. # img_gray = cv2.cvtColor(raw_image, cv2.COLOR_RGB2GRAY)
  34. write_single_img(image_resize, r'C:\Users\Administrator\Desktop\p\01_r.jpg')
  35. return opecv2base64(image_resize)
  36. else:
  37. return opecv2base64(raw_image)
  38. def _get_sign(params, app_key):
  39. sort_dict = sorted(params.items(), key=lambda item: item[0], reverse=False)
  40. sort_dict.append(('app_key', app_key))
  41. rawtext = urlencode(sort_dict).encode()
  42. sha = hashlib.md5()
  43. sha.update(rawtext)
  44. md5text = sha.hexdigest().upper()
  45. return md5text
  46. def please_retry(response, url, data, headers):
  47. status_code = response.status_code
  48. if status_code == 200:
  49. resp = response.json()
  50. if 'ok' != resp.get('msg'):
  51. try_iter = 0
  52. while try_iter < 3:
  53. response = requests.post(url, data=data, headers=headers, timeout=15)
  54. print(resp)
  55. def get_ocr_english_text_raw_format(img, size):
  56. url = 'https://api.ai.qq.com/fcgi-bin/ocr/ocr_generalocr'
  57. headers = {'Content-Type': 'application/x-www-form-urlencoded'}
  58. image_base64 = opecv2base64_stand(img, size) # 得到 base64 编码的数据
  59. nonce_str = ''.join(random.sample(string.ascii_letters + string.digits, 10))
  60. data = {
  61. 'app_id': APP_ID,
  62. 'image': image_base64,
  63. 'time_stamp': str(int(time.time())),
  64. 'nonce_str': nonce_str,
  65. }
  66. sign = _get_sign(data, APP_KEY)
  67. data['sign'] = sign
  68. s = requests.Session()
  69. retries = Retry(total=3,
  70. backoff_factor=0.1,
  71. status_forcelist=[500, 502, 503, 504])
  72. s.mount('https://', HTTPAdapter(max_retries=retries))
  73. # response = requests.post(url, data=data, headers=headers)
  74. response = s.post(url, data=data, headers=headers, timeout=15)
  75. final_response = ''
  76. for _ in range(0, 3):
  77. status_code = response.status_code
  78. if status_code == 200 and 'ok' == response.json().get('msg'):
  79. final_response = response
  80. # print('ok')
  81. break
  82. else:
  83. response = s.post(url, data=data, headers=headers, timeout=15)
  84. # print('retry')
  85. if final_response:
  86. status_code = final_response.status_code
  87. if status_code == 200:
  88. resp = response.json()
  89. if 'ok' != resp.get('msg'):
  90. # print(resp)
  91. raise Exception("ocr error {}: {}!".format(resp.get('ret'), resp.get('msg')))
  92. # print(resp)
  93. else:
  94. raise ValueError('ocr failed, response[{}]'.format(status_code))
  95. else:
  96. raise ValueError('ocr failed, retried three times while no response')
  97. return resp
  98. def ocr_format(resp):
  99. item_list = resp['data']['item_list']
  100. words_str_list = []
  101. for item_index, item in enumerate(item_list):
  102. words_list = item['words']
  103. words_str = ''
  104. for char_index, char_dict in enumerate(words_list):
  105. char = char_dict['character']
  106. if char == '':
  107. char = ' '
  108. words_str = words_str + char
  109. words_str_list.append(words_str.lstrip())
  110. return words_str_list
  111. def get_ocr_english_text(image, size):
  112. resp = get_ocr_english_text_raw_format(image, size)
  113. words_list = ocr_format(resp)
  114. return words_list