You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从Azure Computer Vision API OCR识别的零售收据文本提取结构化数据

我来分享一套实践过的方案,从Azure Computer Vision OCR输出的收据文本里提取商家、购买日期、税费、总计这些结构化数据,核心是结合规则匹配+针对性优化——毕竟零售收据格式五花八门,但核心字段的规律还是有迹可循的。

第一步:获取并预处理OCR输出文本

先把Azure OCR返回的内容整理成方便后续处理的格式:

  • 调用Computer Vision的OCR接口后,从返回的readResult里提取所有行的文本,要么按顺序拼接成完整字符串,要么保留每行的独立文本(后者更适合逐行匹配字段)。
  • 做简单预处理:统一转成小写、去除多余空格和打印乱码符号,减少匹配时的干扰。
第二步:针对每个字段设计匹配逻辑

商家名称

商家名一般在收据最顶部,是1-2行无数字/日期的显眼文本,还常带有特定关键词:

  • 取OCR结果的前3-5行,过滤掉包含金额符号($、¥等)或日期格式的行,剩下的大概率就是商家名。
  • 优先匹配带store、market、cafe、restaurant这类关键词的行。
    示例Python代码片段:
def extract_merchant(ocr_lines):
    merchant_candidates = []
    keywords = ["store", "market", "supermarket", "cafe", "restaurant"]
    for line in ocr_lines[:5]:
        line_lower = line.lower()
        if any(keyword in line_lower for keyword in keywords) and not any(char in line_lower for char in ["$", "/", "-"]):
            merchant_candidates.append(line.strip())
    return " ".join(merchant_candidates) if merchant_candidates else "Unknown Merchant"

购买日期

日期格式相对固定,结合关键词+正则就能精准匹配:

  • 常见格式有MM/DD/YYYY、DD/MM/YYYY、YYYY-MM-DD,还常伴随date、purchased on这类关键词。
  • 用正则+日期解析库辅助识别,示例代码:
import re
from dateutil import parser

def extract_date(ocr_text):
    # 先尝试正则匹配明确格式
    date_patterns = [
        r'\b\d{2}/\d{2}/\d{4}\b',
        r'\b\d{4}-\d{2}-\d{2}\b',
        r'(date:|purchased on:)\s*(\d{2}/\d{2}/\d{4})',
    ]
    for pattern in date_patterns:
        match = re.search(pattern, ocr_text.lower())
        if match:
            return match.group(2) if len(match.groups())>1 else match.group(0)
    # 正则没匹配到的话,用dateutil尝试自动解析
    try:
        parsed_date = parser.parse(ocr_text, fuzzy=True).strftime("%Y-%m-%d")
        return parsed_date
    except:
        return "Unknown Date"

税费

税费常伴随tax、sales tax、vat关键词,后面紧跟金额:

  • 用正则匹配关键词+金额的组合,示例代码:
def extract_tax(ocr_text):
    tax_patterns = [
        r'(tax|sales tax|vat)\s*[:$]?\s*(\d+\.\d{2})',
        r'(\d+\.\d{2})\s*(tax|sales tax|vat)'
    ]
    for pattern in tax_patterns:
        match = re.search(pattern, ocr_text.lower())
        if match:
            # 提取数字部分
            return match.group(2) if match.group(2).replace('.','').isdigit() else match.group(1)
    return "Unknown Tax"

总计

总计一般在收据底部,带total、grand total、amount due关键词,且是金额最大的项:

  • 优先检查OCR结果的最后5行,结合正则匹配,示例代码:
def extract_total(ocr_lines):
    total_patterns = [
        r'(total|grand total|amount due)\s*[:$]?\s*(\d+\.\d{2})',
        r'(\d+\.\d{2})\s*(total|grand total)'
    ]
    # 从底部往上找,提高准确率
    for line in reversed(ocr_lines[-5:]):
        line_lower = line.lower()
        for pattern in total_patterns:
            match = re.search(pattern, line_lower)
            if match:
                amount = match.group(2) if match.group(2).replace('.','').isdigit() else match.group(1)
                return f"${amount}" if not amount.startswith('$') else amount
    return "Unknown Total"
第三步:边缘情况优化
  • 针对格式特别奇葩的收据,可以引入简单的文本分类模型,或者直接用Azure Form Recognizer(专门针对收据/表单的服务,比通用OCR更擅长结构化提取)。
  • 加入校验逻辑:比如总计应该等于商品金额总和+税费(如果能提取商品金额的话),用这个逻辑验证结果准确性。
  • 缓存常见商家的收据格式(比如沃尔玛、星巴克),写专用匹配规则,进一步提升准确率。
第四步:整合完整流程

把上面的函数整合起来,形成一站式提取流程:

def extract_receipt_data(azure_ocr_response):
    # 从Azure OCR响应中提取每行文本
    ocr_lines = [line.text for line in azure_ocr_response.readResult.blocks[0].lines]
    ocr_text = "\n".join(ocr_lines)
    
    return {
        "merchant": extract_merchant(ocr_lines),
        "purchase_date": extract_date(ocr_text),
        "tax": extract_tax(ocr_text),
        "total": extract_total(ocr_lines)
    }

内容的提问来源于stack exchange,提问作者user3116069

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 11:05:52