ocr.py 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. from dataclasses import dataclass
  2. from typing import Any
  3. from core.line_parser import LineParser
  4. from core.parser import *
  5. from core.direction import *
  6. import numpy as np
  7. from paddleocr import PaddleOCR
  8. # 身份证OCR
  9. @dataclass
  10. class IdCardOcr:
  11. ocr: PaddleOCR
  12. # 方向探测器
  13. angle_detector: AngleDetector
  14. # 检测
  15. def predict(self, image: np.ndarray, image_type) -> ():
  16. image_type = int(image_type)
  17. image, angle, result = self._pre_process(image, image_type)
  18. print(f'---------- detect angle: {angle} 角度 --------')
  19. if image_type == 0 and angle != 0 or image_type != 0:
  20. # 角度不为0 需要重新识别,字面
  21. _, _, result = self._ocr(image)
  22. return self._post_process(result, angle, image_type)
  23. # 预处理(旋转图片)
  24. def _pre_process(self, image, image_type) -> (np.ndarray, int, Any):
  25. # pic角度 result(ocr生)
  26. angle, result = self.angle_detector.detect_angle(image, image_type)
  27. if angle == 1:
  28. image = cv2.rotate(image, cv2.ROTATE_90_COUNTERCLOCKWISE)
  29. if angle == 2:
  30. image = cv2.rotate(image, cv2.ROTATE_180)
  31. if angle == 3:
  32. image = cv2.rotate(image, cv2.ROTATE_90_CLOCKWISE)
  33. return image, angle, result
  34. # 获取模型检测结果
  35. def _ocr(self, image):
  36. result = self.ocr.ocr(image, cls=True)
  37. print("------------------")
  38. print(result)
  39. if not result:
  40. raise Exception('无法识别')
  41. confs = [line[1][1] for line in result]
  42. # 将检测到的文字放到一个列表中
  43. txts = [line[1][0] for line in result]
  44. return txts, confs, result
  45. def _post_process(self, result, angle: int, image_type):
  46. filters = [lambda x: x.is_slope, lambda x: x.txt.replace(' ', '').encode('utf-8').isalpha()]
  47. line_parser = LineParser(result, filters)
  48. line_result = line_parser.parse()
  49. conf = line_parser.confidence
  50. if int(image_type) == 0:
  51. parser = FrontParser(line_result)
  52. elif int(image_type) == 1:
  53. parser = BackParser(line_result)
  54. else:
  55. raise Exception('无法识别')
  56. ocr_res = parser.parse()
  57. res = {
  58. "confidence": conf,
  59. "card_type": str(image_type),
  60. "orientation": angle, # 原angle是逆时针,转成顺时针
  61. **ocr_res
  62. }
  63. print(res)
  64. return res