这活儿本来不该我干,但外包团队报的价让我直接笑出声——三万块,就为了把堆成山的纸质报销单变成Excel表格。财务那边催得跟催命一样,说月底关账前必须搞定,我盯着那叠半人高的单据,脑子里就一个念头:这钱不如我自己赚。
其实两年前我用过Tesseract,那玩意儿对规整印刷体还行,但碰上这种皱巴巴、有盖章、有手写备注的发票,识别率直接掉到50%以下,后期人工校对比直接录入还累。这次我重新评估了开源方案,最后锁定了PaddleOCR,不是因为它完美,而是因为它给的“缝补”空间足够大。文档里那句“支持自定义训练”是关键,但我知道根本没时间从头训练模型,我的策略是在预处理和后处理上往死里抠细节。
第一步是扫描件优化。直接用手机拍的图片阴影太重,我用OpenCV搞了个自适应阈值算法,不是简单二值化,而是先做局部对比度增强,把那些淡得快看不见的蓝色复写纸字迹给拉出来。然后针对常见的增值税发票边框,我写了个检测逻辑自动做透视校正,哪怕图片拍歪了,也能把它掰正,这一步让后续的文本区域检测准确率提升了至少30%。
真正的战斗在文本检测和识别阶段。PaddleOCR默认的检测模型对密集、小字号文本容易漏,我调整了DB算法的阈值参数,把检测框变得更“激进”一点,宁可多框一点背景,也不能漏掉一个字符。然后自己写了个合并逻辑,把属于同一行但被误拆的文本框重新拼起来。识别模型我用了他们提供的轻量级版本,但在字典里加入了我们行业里那堆奇葩的缩写和产品编码,大概两百多个词,这招对付专业术语特管用。
后处理才是体现业务逻辑的地方。发票号码、日期、金额这些字段不是识别出来就完事了,得校验。我写了一套规则:发票号码必须符合特定编码规则,日期不能是未来时间,大小写金额必须能对上。对不上的条目自动标红,扔到一个待复核队列里,而不是直接丢弃。最后用PyInstaller打包成一个小工具,丢给财务的实习生,教会她怎么拖文件夹批量处理。
整个开发过程大概挤了四个晚上,每天搞到凌晨两点。工具跑起来之后,处理一张发票的平均时间从人工录入的三分钟压缩到八秒,关键是机器不会累。财务总监后来看到效率报告,特意跑过来问我用了什么黑科技。我没说太多,就告诉他“用了点开源工具和脚本”。那三万块预算自然省下来了,虽然没进我口袋,但下次再有这种急难险重的任务,他们第一时间会想起谁,我心里清楚。
这种自动化一旦跑通,就像在墙上凿开了一个口子。你突然发现,很多重复、枯燥、被认为“本该如此”的人力工作,其实只是没人愿意往前多走两步,去琢磨怎么用代码把它碾碎。时间才是唯一的硬通货,省下来的每一分钟,都是未来对抗更多不确定性的弹药。














