ocr.py 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. from dataclasses import dataclass
  2. from core.parser import *
  3. from core.direction import *
  4. import numpy as np
  5. from typing import List
  6. from core.line_parser import OcrResult, LineParser
  7. from paddleocr import PaddleOCR
  8. from utils.time import timeit
  9. @dataclass
  10. class IdCardOcr:
  11. ocr: PaddleOCR
  12. angle_detector: AngleDetector
  13. def predict(self, image: np.ndarray, image_type: str = '1'):
  14. img_type = int(image_type)
  15. img, angle, result = self._rotate_img(image, img_type)
  16. print(f'---------- detect angle: {angle} 图片角度 ----------')
  17. if angle != 0:
  18. _, _, result = self._ocr(img)
  19. return self._post_process(result, angle, image_type)
  20. @timeit
  21. def _rotate_img(self, image, image_type) -> (np.ndarray, int):
  22. angle, result = self.angle_detector.detect_angle(image, image_type)
  23. return image, angle, result
  24. @timeit
  25. def _ocr(self, image):
  26. result = self.ocr.ocr(image, cls=True)
  27. if not result: raise Exception('无法识别')
  28. confs = [line[1][1] for line in result]
  29. txts = [line[1][0] for line in result]
  30. return txts, confs, result
  31. @timeit
  32. def _post_process(self, result, angle: int, image_type: str):
  33. line_parser = LineParser(result)
  34. line_result = line_parser.parse()
  35. conf = line_parser.confidence
  36. # 0:教育部学历证书电子注册备案表
  37. # 1:教育部学籍在线验证报告
  38. # 2:中国高等教育证书查询结果(零散查询)
  39. if int(image_type) in {0, 1, 2}:
  40. parser = PostParser(line_result)
  41. else:
  42. raise Exception('未传入 image_type')
  43. ocr_res = parser.parse()
  44. res = {
  45. "confidence": conf,
  46. "img_type": str(image_type),
  47. "orientation": angle, # 原angle是逆时针,转成顺时针
  48. **ocr_res
  49. }
  50. print(res)
  51. return res