使用Tesseract-OCR开发发票文本提取遇不规则换行问题,求解决方法
解决Tesseract-OCR发票文本提取中的单词拆分/不规则换行问题
一、图像预处理优化
- 倾斜校正:发票若存在倾斜,会导致Tesseract误判行边界。用OpenCV的
cv2.getRotationMatrix2D和cv2.warpAffine做旋转校正,确保文本行水平。 - 噪声去除与对比度增强:发票常带有阴影、污渍,用阈值处理(
cv2.threshold)或自适应阈值(cv2.adaptiveThreshold)提升文本清晰度;通过形态学操作(cv2.morphologyEx)清除小噪声点。 - 提升分辨率:将图像分辨率调整至300DPI以上,Tesseract对高分辨率文本的行边界识别更精准,减少单词拆分错误。
二、调整Tesseract识别参数
- 指定页面分割模式(PSM):发票属于结构化文档,优先选择PSM 6(假设单块统一文本)或PSM 3(自动页面分割),避免错误拆分行。命令行示例:
tesseract input.jpg output --psm 6 - 保留单词间空格:启用
--oem 3(默认引擎模式)并添加参数-c preserve_interword_spaces=1,强制保留单词间空格,降低单词被拆分行的概率。 - 限定字符集:针对发票常见字符(数字、字母、金额符号等),设置白名单缩小识别范围,减少误判。示例:
-c tessedit_char_whitelist=0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz./$
三、文本后处理修复
- 词典驱动的单词拼接:识别完成后,遍历文本行,检查每行末尾是否为不完整单词(比如词典中不存在的短词),尝试与下一行开头拼接后验证有效性。示例代码:
import enchant # 根据发票语言选择对应词典 word_dict = enchant.Dict("en_US") raw_lines = ["INVO", "ICE", "Total", "Amount: $120"] fixed_lines = [] idx = 0 while idx < len(raw_lines): current_line = raw_lines[idx].strip() # 检查当前行是否为不完整单词,且下一行存在 if idx + 1 < len(raw_lines) and not word_dict.check(current_line): next_segment = raw_lines[idx+1].strip() combined_word = current_line + next_segment if word_dict.check(combined_word): fixed_lines.append(combined_word) idx += 2 continue fixed_lines.append(current_line) idx += 1 - 上下文规则修复:利用发票的固定字段逻辑(如"Invoice Number"、"Total Amount"),检查相邻行是否属于同一字段的内容,进行拼接合并。比如发现"Total"下一行是"Amount: $100",直接合并为"Total Amount: $100"。
四、自定义模型训练(进阶方案)
如果发票有特殊字体或固定排版,收集足够多的发票样本,使用Tesseract的tesstrain工具训练自定义语言模型,让模型熟悉发票的文本布局规则,从根源减少行拆分错误。
内容的提问来源于stack exchange,提问作者İlker Galip ATAK
相关产品推荐
相关产品推荐

