当前位置: 首页 > article >正文

Python结合OCR技术实现高效发票信息提取与自动化处理

1. 为什么需要自动提取发票信息每次月底整理报销单据的时候你是不是也经常对着堆积如山的发票发愁一张张手动录入发票号码、金额、开票日期不仅效率低下还容易出错。我去年在一家电商公司做财务系统优化时发现财务部门每月要处理超过2000张发票3个财务人员全职做这项工作还经常加班。传统的手工录入方式主要存在三个痛点效率低下平均每张发票需要2分钟、错误率高人工录入错误率约3%、难以追溯发现问题后很难定位是哪张发票出错。而使用Python结合OCR技术我们能把单张发票的处理时间缩短到10秒以内准确率可以提升到99%以上。2. 环境准备与工具选型2.1 安装必备Python库工欲善其事必先利其器。我们需要安装几个关键库pip install PyMuPDF paddleocr paddlepaddle openpyxl -i https://pypi.tuna.tsinghua.edu.cn/simple这里解释下各个库的作用PyMuPDF处理PDF文件把发票PDF转换为图片paddleocr百度开源的OCR引擎识别图片中的文字paddlepaddlePaddleOCR的依赖框架openpyxl操作Excel文件用于存储提取的数据我测试过多个OCR引擎PaddleOCR对中文发票的识别准确率最高特别是对印刷体文字的识别效果很好。它的另一个优势是支持多角度文字识别即使发票扫描时有点歪斜也能正确处理。2.2 准备测试发票建议找几种不同类型的发票做测试增值税普通发票最常见电子普通发票PDF格式卷式发票通常比较窄长带有表格的专用发票把这些发票保存为PDF格式放在项目目录下。我建议先用1-2张发票测试确认流程跑通后再批量处理。3. 从PDF提取发票图像3.1 提高图像分辨率的关键技巧很多人在这一步会遇到识别率低的问题主要是因为直接从PDF转换的图像分辨率不够。这是我在实际项目中踩过的坑import fitz # PyMuPDF def pdf_to_img(pdf_path, img_path, zoom8): pdf fitz.open(pdf_path) page pdf.load_page(0) # 处理第一页 # 关键设置提高分辨率 mat fitz.Matrix(zoom, zoom) pix page.get_pixmap(matrixmat, alphaFalse) pix.save(img_path) pdf_to_img(test.pdf, temp.png)zoom参数决定了图像放大倍数我建议设置在4-8之间。太小会导致文字模糊太大又会影响处理速度。如果是特别小的发票比如卷式发票可以尝试更大的zoom值。3.2 批量处理多页PDF实际业务中经常遇到一个PDF包含多张发票的情况def pdf_to_imgs(pdf_path, output_dir): pdf fitz.open(pdf_path) for i in range(len(pdf)): page pdf.load_page(i) mat fitz.Matrix(8, 8) pix page.get_pixmap(matrixmat) pix.save(f{output_dir}/page_{i}.png)这个改进版本会为PDF的每一页生成单独的图片文件保存在指定目录中。我在处理某个月的报销单据时一个PDF里最多遇到过30多张发票这个批量处理方法节省了大量时间。4. 使用PaddleOCR识别发票内容4.1 基础识别配置PaddleOCR的默认配置已经能处理大多数发票但通过调整参数可以进一步提升效果from paddleocr import PaddleOCR ocr PaddleOCR( use_angle_clsTrue, # 启用方向分类器 use_gpuFalse, # 没有GPU时设为False langch, # 中文识别 rec_model_dirNone, # 自定义模型路径 show_logFalse # 关闭详细日志 ) result ocr.ocr(temp.png, clsTrue)use_angle_cls参数特别重要它能自动校正倾斜的文本。我测试过开启后对扫描歪斜的发票识别准确率能提升15%左右。4.2 解析OCR结果OCR返回的结果是分层级的需要仔细处理def parse_invoice(result): invoice_data {} for line in result[0]: text line[1][0] # 识别到的文本 confidence line[1][1] # 置信度 # 提取关键字段 if 发票号码 in text: invoice_data[number] text.split()[-1] elif 开票日期 in text: invoice_data[date] text.split()[-1] elif 金额 in text and 小写 in text: invoice_data[amount] text.split(¥)[-1] return invoice_data这里有个实用技巧不要完全依赖固定位置截取比如用text[5:]这样的方式。因为不同发票的字段前缀可能长短不一用split方法更可靠。我在处理不同省份的发票时发现同样的字段可能有发票号码、发票号、号码等多种写法。4.3 处理识别错误的实用技巧即使是最好的OCR也会出错我们需要建立防御性代码置信度过滤忽略置信度低于0.7的结果格式校验比如发票号码通常是8-10位数字多重验证对关键字段尝试多种匹配方式def validate_invoice(data): # 校验发票号码 if number in data: if not data[number].isdigit() or len(data[number]) not in [8, 10, 12]: data[number] INVALID # 校验金额 if amount in data: try: float(data[amount].replace(,, )) except ValueError: data[amount] 0.00 return data在实际项目中我还会记录识别失败的案例定期用这些数据优化识别逻辑。比如发现某个销售方的名称总是被识别错误就可以针对它添加特殊处理规则。5. 数据存储与自动化流程5.1 存储到Excel表格openpyxl库提供了灵活的Excel操作能力from openpyxl import load_workbook def save_to_excel(data, filename): try: wb load_workbook(filename) except FileNotFoundError: # 新建文件并添加表头 wb Workbook() ws wb.active ws.append([发票号码, 开票日期, 销售方, 金额]) ws wb.active ws.append([ data.get(number, ), data.get(date, ), data.get(seller, ), data.get(amount, ) ]) wb.save(filename)实用建议为每个月的报销单独创建一个Sheet这样后续查询会更方便。我在实现这个功能时还添加了自动创建以当前年月命名的Sheet的功能。5.2 数据库存储方案对于大规模应用建议使用数据库import sqlite3 def init_db(): conn sqlite3.connect(invoices.db) c conn.cursor() c.execute(CREATE TABLE IF NOT EXISTS invoices (id INTEGER PRIMARY KEY AUTOINCREMENT, number TEXT, date TEXT, seller TEXT, amount REAL, file_path TEXT)) conn.commit() conn.close() def save_to_db(data): conn sqlite3.connect(invoices.db) c conn.cursor() c.execute(INSERT INTO invoices VALUES (?,?,?,?,?,?), (None, data[number], data[date], data[seller], data[amount], data[file_path])) conn.commit() conn.close()SQLite是个轻量级选择如果需要多用户访问可以考虑MySQL。我在一个中型企业项目中每天要处理500发票使用MySQL配合适当的索引查询速度依然很快。6. 完整流程封装与优化6.1 构建自动化处理类把各个步骤封装成类会更易于维护class InvoiceProcessor: def __init__(self): self.ocr PaddleOCR(use_angle_clsTrue) def process_pdf(self, pdf_path): # 提取图像 img_path self.pdf_to_img(pdf_path) # OCR识别 result self.ocr.ocr(img_path) # 解析数据 data self.parse_result(result) # 校验数据 validated self.validate_data(data) return validated # 其他方法实现...这种面向对象的设计让代码更清晰也方便后续扩展。比如后来我需要添加发票查重功能只需要在类中添加一个新方法即可。6.2 性能优化技巧处理大量发票时这几个优化很有效GPU加速如果有NVIDIA显卡安装CUDA版本的PaddlePaddle批量处理不要逐张处理而是收集一定数量后统一处理缓存机制对已经处理过的发票跳过OCR步骤# GPU加速示例 ocr PaddleOCR(use_gpuTrue) # 需要先安装GPU版PaddlePaddle # 批量处理 def batch_process(pdf_dir): for pdf_file in Path(pdf_dir).glob(*.pdf): processor.process_pdf(pdf_file)在配备RTX 3060的工作站上使用GPU后处理速度提升了8倍单张发票平均处理时间从12秒降到了1.5秒。7. 实际应用中的问题解决7.1 处理模糊发票遇到扫描质量差的发票时可以尝试这些方法图像预处理使用OpenCV进行锐化、二值化等操作调整OCR参数降低识别阈值尝试识别模糊文字人工复核标记低置信度结果供人工检查import cv2 def preprocess_image(img_path): img cv2.imread(img_path) # 灰度化 gray cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 锐化 kernel np.array([[-1,-1,-1], [-1,9,-1], [-1,-1,-1]]) sharpened cv2.filter2D(gray, -1, kernel) # 二值化 _, binary cv2.threshold(sharpened, 150, 255, cv2.THRESH_BINARY) return binary我在处理一批老发票扫描件时通过这种预处理把识别率从60%提升到了85%。7.2 处理特殊格式发票有些专用发票的格式比较特殊表格型发票需要识别表格线按单元格处理卷式发票文字排列密集需要调整识别区域多联发票需要区分正副本对于表格型发票可以先用OpenCV检测表格线然后分单元格识别def detect_table(img): # 边缘检测 edges cv2.Canny(img, 50, 150) # 霍夫变换检测直线 lines cv2.HoughLinesP(edges, 1, np.pi/180, 100, minLineLength100, maxLineGap10) # 根据直线位置确定单元格 # ... return cells这个功能实现起来比较复杂如果项目预算允许可以考虑使用PaddleOCR的表格识别功能或者专门的表格识别库。

相关文章:

Python结合OCR技术实现高效发票信息提取与自动化处理

1. 为什么需要自动提取发票信息? 每次月底整理报销单据的时候,你是不是也经常对着堆积如山的发票发愁?一张张手动录入发票号码、金额、开票日期,不仅效率低下还容易出错。我去年在一家电商公司做财务系统优化时,发现财…...

BiliBili-UWP:打造Windows平台高效B站观影体验深度指南

BiliBili-UWP:打造Windows平台高效B站观影体验深度指南 【免费下载链接】BiliBili-UWP BiliBili的UWP客户端,当然,是第三方的了 项目地址: https://gitcode.com/gh_mirrors/bi/BiliBili-UWP BiliBili-UWP作为一款专为Windows平台设计的…...

原创:黄大年茶思屋难题揭榜第141期|5道核心题精简公开·未获技术反馈求指正

黄大年茶思屋难题揭榜第141期|5道核心题精简公开未获技术反馈求指正 作者:华夏之光永存 摘要 这五道题我们已完整解题并提交黄大年茶思屋难题揭榜,最终被退回,但平台未给出任何具体技术驳回意见、未指明缺陷、未提供修改方向。我们…...

Windows下QT5.15.2安装MQTT模块全攻略(附分支选择避坑指南)

Windows下QT5.15.2安装MQTT模块全攻略(附分支选择避坑指南) 在物联网开发领域,MQTT协议因其轻量级和高效性成为设备通信的首选方案。对于使用QT5.15.2进行跨平台开发的工程师而言,在Windows环境下正确配置MQTT模块往往是项目起步的…...

GD32F4系列替换STM32F4,HAL库CAN初始化卡死?一个Sleep模式的坑与填坑实录

GD32F4替换STM32F4的CAN初始化陷阱:Sleep模式差异与实战解决方案 最近在将STM32F4项目迁移到GD32F4平台时,遇到了一个令人费解的问题——CAN总线初始化卡死在HAL_CAN_Init()函数中。经过深入排查,发现问题根源在于两款芯片CAN控制器Sleep模式…...

如何让AI创作速度提升3倍?智能缓存技术TeaCache的完整指南

如何让AI创作速度提升3倍?智能缓存技术TeaCache的完整指南 【免费下载链接】ComfyUI-TeaCache 项目地址: https://gitcode.com/gh_mirrors/co/ComfyUI-TeaCache 你是否曾为AI图像和视频生成的速度而烦恼?看着进度条缓慢移动,等待数分…...

大学生专属福利:手把手教你用阿里云ECS免费搭建个人Linux服务器(附7个月白嫖攻略)

大学生零成本玩转云服务器:阿里云ECS实战指南 第一次接触云服务器时,我盯着控制台密密麻麻的选项发懵——地域、实例规格、安全组…这些术语对计算机系大二的我来说,就像天书。直到用学生身份白嫖了阿里云ECS,才真正理解了云计算的…...

告别手动配置:用STM32CubeMX和Arduino库玩转ADS1115与STM32 ADC

告别手动配置:用STM32CubeMX和Arduino库玩转ADS1115与STM32 ADC 在嵌入式开发的世界里,ADC(模数转换器)就像一位不知疲倦的翻译官,将模拟世界的连续信号转换为数字世界能理解的离散数值。然而,传统的寄存器…...

Flux.1-Dev深海幻境在网络安全领域的应用:恶意流量日志可视化分析

Flux.1-Dev深海幻境在网络安全领域的应用:恶意流量日志可视化分析 每天,安全运维中心的告警大屏上,成千上万条日志像瀑布一样滚动。分析师小李紧盯着屏幕,试图从这些密密麻麻的IP地址、端口号和状态码中,分辨出一次真…...

Adams中利用AKISPL和DX函数实现非线性衬套力建模

1. 非线性衬套力建模的核心价值 在机械系统仿真中,非线性衬套力的精确建模直接影响着悬架、发动机支架等关键部件的动态特性分析精度。传统线性模型难以捕捉橡胶衬套、液压衬套等元件在真实工况下的力-位移关系,而Adams中的AKISPL和DX函数组合就像给工程…...

亚马逊 API 签名认证机制详解

在调用亚马逊开放平台、亚马逊云服务(AWS)各类 API 时,签名认证是请求合法的核心门槛,目前主流采用 Signature Version 4(SigV4) 签名机制。它通过对请求内容与密钥做加密计算,实现身份校验、防…...

3分钟解决NCM格式难题:ncmdumpGUI让你的音乐重获自由 [特殊字符]

3分钟解决NCM格式难题:ncmdumpGUI让你的音乐重获自由 🎵 【免费下载链接】ncmdumpGUI C#版本网易云音乐ncm文件格式转换,Windows图形界面版本 项目地址: https://gitcode.com/gh_mirrors/nc/ncmdumpGUI 还在为网易云音乐的NCM格式文件…...

SQL Server数据库标记为SUSPECT的紧急修复指南:从单用户到多用户模式的完整恢复流程

1. 数据库被标记为SUSPECT的常见原因 数据库突然变成SUSPECT状态,就像电脑突然蓝屏一样让人措手不及。我遇到过最典型的情况是机房突然断电,导致SQL Server没来得及完成所有事务就强制关闭了。这种情况下,数据库引擎为了保护数据完整性&#…...

高效掌握开源工具抖音直播录制:从基础搭建到高级应用指南

高效掌握开源工具抖音直播录制:从基础搭建到高级应用指南 【免费下载链接】DouyinLiveRecorder 项目地址: https://gitcode.com/gh_mirrors/do/DouyinLiveRecorder 一、直播内容捕获工具的核心价值解析 核心价值:实现直播内容自动化捕获与管理&…...

DW_apb_uart初始化全流程解析:从时钟门控到中断配置的15个关键步骤

DW_apb_uart深度初始化指南:从寄存器配置到中断优化的15个实战要点 在嵌入式系统开发中,UART通信作为最基础却又最关键的接口之一,其稳定性和性能直接影响整个系统的可靠性。DW_apb_uart作为业界广泛使用的高性能UART IP核,其初始…...

原神帧率解锁技术突破:从性能瓶颈到效能释放的全流程优化指南

原神帧率解锁技术突破:从性能瓶颈到效能释放的全流程优化指南 【免费下载链接】genshin-fps-unlock unlocks the 60 fps cap 项目地址: https://gitcode.com/gh_mirrors/ge/genshin-fps-unlock 诊断性能瓶颈:揭开帧率限制的技术根源 识别帧率锁定…...

Java 使用国密算法实现数据加密传输

本文是混合加密:前端 SM2 SM4,后端 Spring Boot Hutool 解密的完整示例。 方案的逻辑是: 前端随机生成一个 SM4 key 用 SM4 加密整个业务 JSON 用后端提供的 SM2 公钥 加密这个 SM4 key 后端先用 SM2 私钥 解出 SM4 key 再用 SM4 解出…...

Java面试-test

test...

认知迷雾计划:用废话消耗AI算力

被低效会议吞噬的AI资源在软件测试领域,AI驱动工具正逐步承担自动化测试、缺陷预测、日志分析等高价值任务。然而,一种名为“认知迷雾”的隐形威胁——即低效会议产生的海量冗余信息——正在持续消耗宝贵算力资源。本文从测试工程视角,剖析废…...

BM3D算法深度解析:为什么它至今仍是图像去噪的黄金标准?

BM3D算法深度解析:为什么它至今仍是图像去噪的黄金标准? 在数字图像处理领域,去噪技术一直是研究的热点与难点。从早期的均值滤波到小波变换,再到如今的深度学习,各种方法层出不穷。然而,在这片技术迭代的浪…...

字节跳动的Trae的使用感受,及对比腾讯小龙虾使用场景

一、Trae的使用 Trae支持多种模型,官网下载安装后,直接在对话框描述你的需求, 比如,我这里需求是帮我按照ui设计图,帮我生成小程序页面: A. 上传磨刀或蓝狐页面设计图,例如:蓝湖选中…...

YOLO X Layout实战:商业报告智能解析,快速提取表格与图表数据

YOLO X Layout实战:商业报告智能解析,快速提取表格与图表数据 1. 商业文档处理的痛点与解决方案 在金融分析、市场研究等专业领域,我们经常需要处理大量商业报告。这些PDF或扫描件文档中包含大量有价值的数据表格和图表,但手动提…...

PyQt5实战:手把手教你打造PPT风格的颜色+线型组合下拉框(附完整源码)

PyQt5高级控件开发:打造Office风格的颜色与线型组合选择器 在桌面应用开发中,提供直观、专业的样式选择控件是提升用户体验的关键。本文将深入探讨如何利用PyQt5构建一个功能完备的Office风格组合选择器,集成颜色选择、线型设置和粗细调整等核…...

远程收款好用服务商

在数字化支付日益普及的今天,远程收款成为许多商家和创业者的重要需求。然而,由于各种风控限制,微信支付、支付宝等主流支付平台在异地收款时常常出现异常提示或风险拦截,给用户带来了不少困扰。本文将对比分析几家提供远程收款服…...

CGAL Point_set_processing 点集处理函数自查表

参考来源: CGAL 6.1.1 - Point Set Processing: Algorithms 一、尺度 / K 值估算 返回值函数名作用用法示例size_testimate_global_k_neighbor_scale估算全局最优 K 邻域estimate_global_k_neighbor_scale(points)FTestimate_global_range_scale估算全局最优搜索…...

从零构建IoT图像流:ESP32-CAM自动抓拍与App Inventor安卓端动态展示

1. ESP32-CAM硬件准备与环境搭建 第一次接触ESP32-CAM时,我被这个小巧的硬件惊艳到了——它集成了摄像头模块和WiFi功能,价格却不到百元。不过在实际操作中,我发现新手最容易卡在硬件连接环节。这里分享几个实测有效的技巧: 供电问…...

大模型LLM ACA - ACP认证考试模拟试卷一

目录 一、大模型LLM ACA - ACP认证考试 二、大模型LLM ACA - ACP认证考试模拟试卷 (一)单选题:70 题 1 分 70 分 1. 在代码中,answer_correctness 指标的主要作用是什么? 2. 在ask_llm_route函数中,…...

Keil软件仿真中STM32F407卡在HSE就绪问题的Debugconfig.ini配置指南

1. 为什么STM32F407软件仿真会卡在HSE就绪? 最近在用Keil MDK调试STM32F407项目时,发现一个奇怪现象:软件仿真总是卡在"Wait till HSE is ready"这个地方,死活进不了main函数。这个问题困扰了我整整两天,最后…...

Zotero效率翻倍!Zutilo插件保姆级配置指南(附我常用的10个快捷键方案)

Zotero效率革命:用Zutilo插件打造键盘流文献工作流 每天面对数百篇文献,你是否厌倦了在鼠标和键盘间反复切换?科研老手都知道,真正的效率提升往往来自那些能减少手指移动距离的微小优化。Zutilo正是Zotero生态中那个被严重低估的…...

Verilog握手信号实战:如何用valid/ready搭建高效数据流水线(附完整代码)

Verilog握手信号实战:如何用valid/ready搭建高效数据流水线(附完整代码) 在FPGA开发中,数据流水线是实现高性能计算的关键架构。但当我们面对不同处理速度的模块时,如何确保数据既不丢失又不阻塞?valid/rea…...