ocr_utils.py 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. import os
  2. # 禁用所有可能导致 "could not execute a primitive" 错误的优化
  3. os.environ["FLAGS_use_mkldnn"] = "0"
  4. os.environ["FLAGS_prim_skip_onednn"] = "1"
  5. os.environ["FLAGS_enable_pir_api"] = "0"
  6. os.environ["FLAGS_use_cuda_managed_memory"] = "0"
  7. os.environ["KMP_DUPLICATE_LIB_OK"] = "TRUE"
  8. os.environ["OMP_NUM_THREADS"] = "1"
  9. import cv2
  10. import re
  11. from paddleocr import PaddleOCR
  12. # 初始化 PaddleOCR(只需初始化一次,可复用)
  13. # 使用 CPU 模式并禁用可能的优化
  14. ocr = PaddleOCR(
  15. use_angle_cls=True,
  16. lang='ch',
  17. use_gpu=False,
  18. enable_mkldnn=False,
  19. cpu_threads=1
  20. )
  21. def extract_text_from_image(image_path):
  22. """使用 PaddleOCR 从图片中提取文本"""
  23. try:
  24. # 使用 PaddleOCR 进行识别
  25. result = ocr.ocr(image_path)
  26. # 提取所有文本
  27. text_list = []
  28. if result and result[0]:
  29. for line in result[0]:
  30. text_list.append(line[1][0])
  31. # 合并所有识别的文本
  32. full_text = '\n'.join(text_list)
  33. return full_text.strip()
  34. except Exception as e:
  35. print(f"OCR 识别错误: {str(e)}")
  36. return ""
  37. def extract_id_card_info(image_path):
  38. """
  39. 从身份证图片中提取完整信息
  40. 返回: {
  41. 'name': 姓名,
  42. 'gender': 性别,
  43. 'nation': 民族,
  44. 'birth': 出生日期,
  45. 'address': 地址,
  46. 'id_number': 身份证号
  47. }
  48. """
  49. try:
  50. # 使用 PaddleOCR 识别身份证
  51. result = ocr.ocr(image_path)
  52. name = None
  53. gender = None
  54. nation = None
  55. birth = None
  56. address = None
  57. id_number = None
  58. if result and result[0]:
  59. all_text = []
  60. for line in result[0]:
  61. text = line[1][0]
  62. confidence = line[1][1]
  63. all_text.append(text)
  64. # 识别身份证号(18位或15位)
  65. id_match = re.search(r'\d{17}[\dxX]|\d{15}', text)
  66. if id_match and confidence > 0.8:
  67. id_number = id_match.group(0).upper()
  68. # 识别姓名
  69. if '姓名' in text:
  70. name_match = re.search(r'姓名[:\s]*([^\s]+)', text)
  71. if name_match:
  72. name = name_match.group(1)
  73. elif not name and confidence > 0.9:
  74. name_match = re.search(r'^[一-龥]{2,4}$', text)
  75. if name_match and not any(kw in name_match.group(0) for kw in ['姓名', '性别', '民族', '出生', '住址', '公民']):
  76. name = name_match.group(0)
  77. # 识别性别
  78. if '性别' in text:
  79. gender_match = re.search(r'性别[:\s]*(男|女)', text)
  80. if gender_match:
  81. gender = gender_match.group(1)
  82. elif text in ['男', '女'] and confidence > 0.9:
  83. gender = text
  84. # 识别民族
  85. if '民族' in text:
  86. nation_match = re.search(r'民族[:\s]*([^\s]+)', text)
  87. if nation_match:
  88. nation = nation_match.group(1)
  89. elif confidence > 0.9 and re.match(r'^[一-龥]{1,4}族$', text):
  90. nation = text
  91. # 识别出生日期
  92. if '出生' in text:
  93. birth_match = re.search(r'(\d{4})年(\d{1,2})月(\d{1,2})日', text)
  94. if birth_match:
  95. birth = f"{birth_match.group(1)}-{birth_match.group(2).zfill(2)}-{birth_match.group(3).zfill(2)}"
  96. elif not birth:
  97. birth_match = re.search(r'(\d{4})年(\d{1,2})月(\d{1,2})日', text)
  98. if birth_match:
  99. birth = f"{birth_match.group(1)}-{birth_match.group(2).zfill(2)}-{birth_match.group(3).zfill(2)}"
  100. # 识别住址
  101. if '住址' in text or '址' in text:
  102. address_match = re.search(r'住?址[:\s]*(.+)', text)
  103. if address_match:
  104. address = address_match.group(1)
  105. # 如果住址没有完整识别,尝试合并多行文本
  106. if not address:
  107. full_text = '\n'.join(all_text)
  108. address_match = re.search(r'住?址[:\s]*([^\n]+(?:\n[^姓名性别民族出生公民身份号]+)*)', full_text)
  109. if address_match:
  110. address = address_match.group(1).replace('\n', '')
  111. return {
  112. 'name': name,
  113. 'gender': gender,
  114. 'nation': nation,
  115. 'birth': birth,
  116. 'address': address,
  117. 'id_number': id_number
  118. }
  119. except Exception as e:
  120. print(f"身份证识别错误: {str(e)}")
  121. return {
  122. 'name': None,
  123. 'gender': None,
  124. 'nation': None,
  125. 'birth': None,
  126. 'address': None,
  127. 'id_number': None
  128. }
  129. # 示例调用
  130. if __name__ == "__main__":
  131. # 测试普通 OCR
  132. text = extract_text_from_image('path_to_image.png')
  133. print("提取的文本:", text)
  134. # 测试身份证识别
  135. id_info = extract_id_card_info('path_to_id_card.jpg')
  136. print("身份证信息:", id_info)