logo

Python+OCR自动识别火车发票号码全流程解析

作者:暴富20212025.09.18 11:48浏览量:0

简介:本文详细介绍了如何利用Python结合OCR技术自动识别火车发票中的发票号码,包括环境准备、OCR引擎选择、图像预处理、发票号码定位与识别等关键步骤,并提供了完整的代码示例和优化建议,帮助开发者高效实现自动化发票信息提取。

Python+OCR自动识别火车发票号码全流程解析

一、背景与需求分析

在财务报销、税务审计等场景中,火车发票作为重要的交通费用凭证,其发票号码的准确提取至关重要。传统的人工录入方式效率低下且易出错,而通过Python结合OCR(光学字符识别)技术,可以实现火车发票号码的自动化识别,大幅提升工作效率。本文将详细介绍如何利用Python和OCR技术,从火车发票图像中准确提取发票号码。

二、环境准备与依赖安装

1. Python环境

建议使用Python 3.6及以上版本,确保兼容性和性能。可通过Anaconda或直接安装Python官方版本。

2. OCR引擎选择

目前主流的OCR引擎包括Tesseract、EasyOCR、PaddleOCR等。其中,Tesseract开源免费,支持多种语言;EasyOCR基于深度学习,识别准确率高;PaddleOCR是百度开源的OCR工具包,特别适合中文识别。本文以PaddleOCR为例进行介绍。

3. 依赖库安装

  1. pip install paddlepaddle paddleocr opencv-python numpy
  • paddlepaddle:PaddlePaddle深度学习框架。
  • paddleocr:基于PaddlePaddle的OCR工具包。
  • opencv-python:用于图像处理。
  • numpy:数值计算库。

三、图像预处理

火车发票图像可能存在倾斜、光照不均等问题,影响OCR识别效果。因此,在识别前需要进行图像预处理。

1. 图像二值化

将彩色图像转换为灰度图,再通过阈值处理将图像二值化,增强文字与背景的对比度。

  1. import cv2
  2. import numpy as np
  3. def preprocess_image(image_path):
  4. # 读取图像
  5. img = cv2.imread(image_path)
  6. # 转换为灰度图
  7. gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
  8. # 二值化处理
  9. _, binary = cv2.threshold(gray, 150, 255, cv2.THRESH_BINARY_INV)
  10. return binary

2. 图像倾斜校正

通过霍夫变换检测直线,计算倾斜角度并校正图像。

  1. def correct_skew(image):
  2. # 边缘检测
  3. edges = cv2.Canny(image, 50, 150, apertureSize=3)
  4. # 霍夫变换检测直线
  5. lines = cv2.HoughLinesP(edges, 1, np.pi/180, threshold=100, minLineLength=100, maxLineGap=10)
  6. # 计算倾斜角度
  7. angles = []
  8. for line in lines:
  9. x1, y1, x2, y2 = line[0]
  10. angle = np.arctan2(y2 - y1, x2 - x1) * 180. / np.pi
  11. angles.append(angle)
  12. median_angle = np.median(angles)
  13. # 旋转校正
  14. (h, w) = image.shape[:2]
  15. center = (w // 2, h // 2)
  16. M = cv2.getRotationMatrix2D(center, median_angle, 1.0)
  17. rotated = cv2.warpAffine(image, M, (w, h), flags=cv2.INTER_CUBIC, borderMode=cv2.BORDER_REPLICATE)
  18. return rotated

四、发票号码定位与识别

1. 使用PaddleOCR进行识别

PaddleOCR提供了简洁的API,可直接调用进行文字识别

  1. from paddleocr import PaddleOCR
  2. def recognize_invoice_number(image_path):
  3. # 初始化PaddleOCR
  4. ocr = PaddleOCR(use_angle_cls=True, lang="ch")
  5. # 读取并预处理图像
  6. img = preprocess_image(image_path)
  7. img = correct_skew(img)
  8. # 识别文字
  9. result = ocr.ocr(img, cls=True)
  10. # 提取发票号码(假设发票号码位于特定区域或具有特定格式)
  11. invoice_number = None
  12. for line in result:
  13. for word_info in line:
  14. word = word_info[1][0]
  15. # 简单规则匹配发票号码(实际应用中需更复杂的规则)
  16. if len(word) == 10 and word.isdigit(): # 假设发票号码为10位数字
  17. invoice_number = word
  18. break
  19. if invoice_number:
  20. break
  21. return invoice_number

2. 发票号码定位优化

实际应用中,发票号码可能位于发票的特定区域(如右上角或底部)。可通过以下方式优化定位:

  • 模板匹配:预先定义发票号码区域的模板,通过模板匹配定位。
  • 关键点检测:利用深度学习模型检测发票上的关键点(如发票号码区域),再裁剪该区域进行识别。

五、完整代码示例与测试

1. 完整代码

  1. import cv2
  2. import numpy as np
  3. from paddleocr import PaddleOCR
  4. def preprocess_image(image_path):
  5. img = cv2.imread(image_path)
  6. gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
  7. _, binary = cv2.threshold(gray, 150, 255, cv2.THRESH_BINARY_INV)
  8. return binary
  9. def correct_skew(image):
  10. edges = cv2.Canny(image, 50, 150, apertureSize=3)
  11. lines = cv2.HoughLinesP(edges, 1, np.pi/180, threshold=100, minLineLength=100, maxLineGap=10)
  12. angles = []
  13. for line in lines:
  14. x1, y1, x2, y2 = line[0]
  15. angle = np.arctan2(y2 - y1, x2 - x1) * 180. / np.pi
  16. angles.append(angle)
  17. median_angle = np.median(angles)
  18. (h, w) = image.shape[:2]
  19. center = (w // 2, h // 2)
  20. M = cv2.getRotationMatrix2D(center, median_angle, 1.0)
  21. rotated = cv2.warpAffine(image, M, (w, h), flags=cv2.INTER_CUBIC, borderMode=cv2.BORDER_REPLICATE)
  22. return rotated
  23. def recognize_invoice_number(image_path):
  24. ocr = PaddleOCR(use_angle_cls=True, lang="ch")
  25. img = preprocess_image(image_path)
  26. img = correct_skew(img)
  27. result = ocr.ocr(img, cls=True)
  28. invoice_number = None
  29. for line in result:
  30. for word_info in line:
  31. word = word_info[1][0]
  32. if len(word) == 10 and word.isdigit():
  33. invoice_number = word
  34. break
  35. if invoice_number:
  36. break
  37. return invoice_number
  38. # 测试
  39. image_path = "train_invoice.jpg" # 替换为实际发票图像路径
  40. invoice_number = recognize_invoice_number(image_path)
  41. print(f"识别到的发票号码: {invoice_number}")

2. 测试与优化

  • 测试数据集:收集多张不同光照、角度的火车发票图像进行测试。
  • 性能优化:调整OCR参数(如语言模型、识别阈值)、优化图像预处理步骤。
  • 错误处理:添加异常处理,如图像读取失败、OCR识别为空等情况。

六、总结与展望

本文介绍了如何利用Python和PaddleOCR技术自动识别火车发票中的发票号码,包括环境准备、图像预处理、OCR识别等关键步骤。通过实际代码示例和测试,验证了方法的可行性。未来,可进一步探索深度学习模型在发票号码定位中的应用,提升识别的准确率和鲁棒性。

相关文章推荐

发表评论