基于Python与OCR的票据图片批量数据提取实战

小岛来信
小岛来信
发布时间:2026-10-12| 3人浏览过
原创

面对大量发票或承兑单据的图片,手动录入效率极低。本文演示如何使用Python脚本读取图片、按区域裁剪、调用OCR引擎识别关键字段,并将包含中文大写金额的票据数据统一清洗后导出为Excel表格,适用于财务对账、单据归档等场景。

需求分析与环境配置

该方案的核心目标是:将指定文件夹内的票据图片逐张打开,利用图像坐标截取需要提取的文本区域,调用OCR工具进行识别,对中文大写金额进行数值化转换,最后将结果按固定表头写入Excel文件。操作前需确保以下基础条件已就绪:

  • 系统组件:安装 Tesseract-OCR 与 ImageMagick,用于底层图像解析与字符识别支撑。
  • 运行环境:Python 3.7+。
  • 核心库:PIL(图像处理)、io与os(文件流遍历)、pyocr(通用OCR封装)、cnocr(中文高精度识别)、xlwt(Excel写入)。
  • 模型初始化:CnOcr首次运行会自动下载中文预训练模型,需保持网络畅通。

第1步:编写中文大写金额转换逻辑

票据中的金额常以汉字大写形式呈现(如“贰拾万元整”),直接导入表格不利于后续统计。需在预处理阶段将其转换为阿拉伯整数,便于Excel计算与筛选。

def chineseNumber2Int(strNum: str):
    result = 0
    temp = 1  # 存放一个单位的基数,如十万
    count = 0  # 记录连续出现的单位数
    cnArr = ['壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖']
    chArr = ['拾', '佰', '仟', '万', '亿']
    
    for char in strNum:
        base_found = False
        for val_idx, digit in enumerate(cnArr):
            if char == digit:
                if count != 0:
                    result += temp
                    count = 0
                temp = val_idx + 1
                base_found = True
                break
        if not base_found:
            for unit_idx, unit in enumerate(chArr):
                if char == unit:
                    multipliers = [10, 100, 1000, 10000, 100000000]
                    temp *= multipliers[unit_idx]
                count += 1
    
    result += temp
    return result

票据金额示例‘贰拾万元整’

输入任意标准大写格式字符串,该函数即可返回对应的整型数值。例如传入“贰拾万元整”将输出 200000,有效简化了表格后期的数据清洗流程。

第2步:按固定坐标裁剪与OCR识别

对于版面固定的票据,最稳定且高效的方式是预先标定各字段的像素坐标,利用 PIL.Image.crop() 精确切分目标区域,再分别交由适合的OCR引擎处理。日期与纯数字区域通常适合传统OCR,中文密集区建议使用 CnOcr。

可通过系统自带画图软件打开测试图片,拖动鼠标查看左下角状态栏的实时坐标,据此划定左上角 (left, top) 与右下角 (right, bottom) 边界。

绘图软件坐标定位示例

左下角光标坐标显示

字段提取函数结构统一,以下为其中两个典型示例。实际项目中可将坐标、引擎调用封装为配置字典,按需循环调用:

def extract_date(new_img, tool):
    # 出票日期区域
    cropped = new_img.crop((80, 143, 162, 162))
    return str(tool.image_to_string(cropped))

def extract_amount(new_img, ocr_engine):
    # 金额区域
    cropped = new_img.crop((224, 355, 585, 380))
    raw_text = "".join(ocr_engine.ocr("temp_crop.png")[0])
    return chineseNumber2Int(raw_text)

第3步:批量遍历与Excel结构化导出

完成单个文件的处理逻辑后,进入批量执行环节。使用 os.walk 扫描目标文件夹,依次读取二进制流转为PIL图像对象,执行上述提取函数,并按行列写入工作表。

注意:原草稿示例中将 book.save() 放在了循环体内,会导致频繁覆盖或产生冗余文件。正确做法是在循环外统一保存,且表头仅写入一次。

import os
from PIL import Image as PI
import io
from cnocr import CnOcr
import pyocr
import xlwt

# 1. 初始化引擎
ocr_cn = CnOcr()
tool_tess = pyocr.get_available_tools()[0]

file_dir = 'img'
workbook = xlwt.Workbook(encoding='utf-8')
sheet = workbook.add_sheet('票据明细', cell_overwrite_ok=True)

# 2. 写入表头(循环外仅执行一次)
headers = ('年份','出票日期','金额','出票人','付款行全称','汇票到期日','备注')
for col_idx, h in enumerate(headers):
    sheet.write(0, col_idx, h)

count = 1
# 3. 遍历处理所有图片
for root, _, filenames in os.walk(file_dir):
    for fname in filenames:
        img_path = os.path.join(root, fname)
        with open(img_path, 'rb') as f:
            pil_img = PI.open(io.BytesIO(f.read()))
        
        try:
            dt = extract_date(pil_img, tool_tess)
            amt = extract_amount(pil_img, ocr_cn)
            # 其余字段调用对应函数...
            
            sheet.write(count, 0, dt[:4])          # 年份
            sheet.write(count, 1, dt[5:])          # 月日
            sheet.write(count, 2, amt)             # 数值化金额
            # sheet.write(count, 3, txt_drawer)
            # sheet.write(count, 4, txt_payer)
            # ...其他列
            count += 1
        except Exception as e:
            print(f"跳过异常文件 {fname}: {e}")

# 4. 统一保存(放在最终出口)
workbook.save('票据数据汇总.xls')

常见报错与参数调整

  1. 识别结果为空或乱码:裁剪区域未完全覆盖文字,或背景噪声过重。需微调 crop 坐标,并在识别前增加灰度二值化处理 image.convert('L')。
  2. CnOcr模型缺失报错:首次运行会在用户目录下创建 .cache/cnocr 并下载权重。若服务器无外网,需手动下载模型包并设置环境变量 CNOCR_MODEL_PATH。
  3. 横竖版或分辨率不一致:硬编码坐标强依赖原始图片尺寸。若票据存在缩放,应引入相对比例换算(如将坐标乘以 actual_width / 1080),或改用版面分析算法动态定位。

总结

本方案通过“坐标裁剪+双引擎识别+大写转数字”的组合策略,实现了固定格式票据数据的自动化提取与表格化输出。脚本可直接嵌入定时任务或财务SOP流程中,大幅降低人工录入成本。在实际部署前,请务必先用少量样本验证坐标精度与金额转换的正确性。以上就是基于Python与OCR的票据图片批量数据提取的详细内容,更多关于Python票据识别与自动化办公的资料请关注本站其它相关文章!

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。