OCR识别核心是图像预处理而非调参:先灰度化与自适应二值化,再开运算去噪,接着倾斜校正,最后缩放至300 DPI;中文需指定lang='chi_sim'并配置tessdata,PSM模式按场景选用。

用 Python 做 OCR 识别,核心是让图像“更适合被 Tesseract 看懂”——不是靠调高参数,而是把图片先处理干净。Tesseract 本身不擅长处理模糊、倾斜、低对比度或带噪点的图,所以预处理比换模型更关键。
安装与基础配置
Tesseract 需要系统级安装(不只是 pip),Python 端用 pytesseract 调用:
-
macOS:用
brew install tesseract,再pip install pytesseract opencv-python numpy - Windows:去 UB-Mannheim 官网 下安装包,勾选添加到 PATH;之后 pip 安装同上
- 验证是否成功:
import pytesseract; print(pytesseract.get_tesseract_version()) - 中文识别必须指定语言:
lang='chi_sim'(简体)或'chi_tra'(繁体),需提前下载对应训练数据(tessdata 仓库)并放入 Tesseract 的tessdata目录
图像预处理四步法
多数识别失败,问题出在输入图像。以下四步按顺序做,每步解决一类常见干扰:
-
灰度化 + 二值化:去掉颜色干扰,突出文字区域。推荐用 OpenCV 的自适应阈值(
cv2.adaptiveThreshold),比全局阈值更适应光照不均的图 -
去噪 & 细化:用形态学操作(如
cv2.morphologyEx中的开运算)清除散点噪点;对细字体可加cv2.ximgproc.thinning(需 opencv-contrib-python) -
倾斜校正:检测文字行角度,用仿射变换旋转。简单方法是霍夫线检测后取中位角;也可用
skimage.transform.rotate配合投影法粗估 -
分辨率提升:Tesseract 推荐 300 DPI。若原图太小,用
cv2.resize放大(插值选cv2.INTER_CUBIC),但别过度放大,否则边缘发虚
实战代码片段(含注释)
以下是一个端到端可运行的精简流程,处理一张扫描件截图:
立即学习“Python免费学习笔记(深入)”;
import cv2 import numpy as np import pytesseractdef preprocess(img_path): img = cv2.imread(img_path, cv2.IMREAD_GRAYSCALE)
自适应二值化
binary = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2) # 开运算去噪 kernel = np.ones((2,2), np.uint8) cleaned = cv2.morphologyEx(binary, cv2.MORPH_OPEN, kernel) # 放大至 300 DPI 等效尺寸(假设原始为 72 DPI,放大 ~4.2x) h, w = cleaned.shape resized = cv2.resize(cleaned, (int(w*4.2), int(h*4.2)), interpolation=cv2.INTER_CUBIC) return resizedimg_pre = preprocess("receipt.jpg") text = pytesseract.image_to_string(img_pre, lang='chi_sim', config='--psm 6') print(text.strip())
注意:
--psm 6表示“假设为单块均匀文本”,适合常规文档;表格或混排内容可试--psm 4(分段)或--psm 1(自动页面分割)避坑提醒
这些细节不处理,准确率会断崖下跌:
- Tesseract 对阴影、水印、底纹极度敏感——预处理时先用
cv2.inpaint或背景建模抹掉大面积灰斑 - 中文标点(如《》【】)识别率偏低,可在后处理中用正则替换近似字符(如 “〈” → “《”)
- 小字号(<10px)或手写体建议换专用模型(PaddleOCR、EasyOCR),Tesseract 不是万能的
- 识别结果含大量空行或乱码?大概率是二值化阈值不合适,改用 Otsu 法(
cv2.threshold(..., cv2.THRESH_OTSU))自动寻优










