fix: 凭证号提取改进

- 双管线OCR:原图提取头部(凭证号/日期) + 预处理提取表格
- 正则兼容更宽松格式(空格、破折号)
- 修复预处理破坏小字导致65/66号凭证漏识别的问题
This commit is contained in:
xiaoxue_admin 2026-06-22 10:13:48 +08:00
parent b86cf8d77f
commit 801e492fa9
2 changed files with 38 additions and 10 deletions

View File

@ -43,13 +43,20 @@ class K3VoucherParser:
except:
pass
elif '凭证号' in text:
m = re.search(r'[\u8bb0\u51ed\u8bc1]-\s*(\d+)', text)
elif '凭证' in text:
# 兼容各种格式:记-45、记 - 45、记-451/3、45(1/3)
m = re.search(r'[记凭证]\s*[-—]\s*(\d+)', text)
if m:
result['voucher_no'] = int(m.group(1))
m2 = re.search(r'(\d+)\d+/\d+', text) # 多页凭证1231/3
if m2:
result['voucher_no'] = int(m2.group(1))
if not result['voucher_no']:
m2 = re.search(r'(?:记\s*)?[-—]?\s*(\d+)\s*[(]\d+[/]\d+[)]', text)
if m2:
result['voucher_no'] = int(m2.group(1))
# 兜底:直接找"凭证号"后面的数字
if not result['voucher_no']:
m3 = re.search(r'凭证号\s*[:]\s*记?\s*[-—]?\s*(\d+)', text)
if m3:
result['voucher_no'] = int(m3.group(1))
elif '附件数' in text:
m = re.search(r'附件数[:](\d+)', text)

31
kocr.py
View File

@ -159,7 +159,19 @@ def process_single(image_path, config, output_path=None, verbose=False, mark_don
print(f" 📊 图像分析: 类型={quality.photo_type}, "
f"亮度={quality.brightness}, 模糊={quality.blur_score}")
# 2. 自动调参 + 预处理
# 2. 双管线先对原图OCR提取头部凭证号、日期对小字更敏感
ocr_config = config.get('ocr', {})
# 2a. 原图OCR → 提取头部信息(预处理会破坏小字)
if verbose:
print(f" 📋 原图OCR提取头部...")
lines_raw = run_ocr(img, ocr_config, quality.photo_type, verbose=verbose)
parser_raw = K3VoucherParser(lines_raw)
header_info = parser_raw.parse()
if verbose and header_info['voucher_no']:
print(f" ✅ 原图识别到凭证号: 记-{header_info['voucher_no']}")
# 2b. 自动调参 + 预处理 → 提取表格内容
preproc_config = config.get('preprocessing', {})
preprocessor = VoucherPreprocessor.from_config(preproc_config, quality.photo_type)
processed = preprocessor.process(img)
@ -169,17 +181,26 @@ def process_single(image_path, config, output_path=None, verbose=False, mark_don
f"去阴影={preprocessor.remove_shadow}, "
f"锐化={preprocessor.sharpen}")
# 3. OCR 识别(自动选参数)
ocr_config = config.get('ocr', {})
lines = run_ocr(processed, ocr_config, quality.photo_type, verbose=verbose)
if verbose:
print(f" OCR: {len(lines)} 行文字")
print(f" OCR: {len(lines)} 行文字(预处理后)")
# 4. 凭证解析
# 3. 解析(合并原图头部 + 预处理表格)
parser = K3VoucherParser(lines)
voucher = parser.parse()
# 如果原图识别到了凭证号但预处理后没识别到,补回来
if voucher['voucher_no'] is None and header_info['voucher_no'] is not None:
voucher['voucher_no'] = header_info['voucher_no']
if verbose:
print(f" ✅ 使用原图凭证号: 记-{header_info['voucher_no']}")
# 同理补日期
if voucher['date'] is None and header_info['date'] is not None:
voucher['date'] = header_info['date']
if verbose:
print(f" ✅ 使用原图日期: {header_info['date'].strftime('%Y-%m-%d')}")
if verbose:
print(f" 公司: {voucher['company']}")
print(f" 日期: {voucher['date'].strftime('%Y-%m-%d') if voucher['date'] else '未识别'}")