影像技术实战07:OCR 识别率低?图像预处理、版面清洗与 Tesseract 调参完整方案 影像技术实战07OCR 识别率低图像预处理、版面清洗与 Tesseract 调参完整方案一、问题场景OCR 模型没换为什么识别率差这么多OCR 是影像系统里非常常见的能力。业务场景包括发票识别表格识别合同扫描件识别截图文字提取视频字幕提取图片内容审核文档数字化很多人第一次接 OCR会直接importpytesseractfromPILimportImage textpytesseract.image_to_string(Image.open(input.jpg))print(text)然后发现中文识别乱码英文还行数字识别错图片稍微倾斜就识别很差背景复杂时识别率下降小字识别不出来表格线干扰识别截图压缩后识别错误多灰底文档识别效果差标点符号混乱同一张图预处理前后差异巨大这篇文章解决的问题是如何通过图像预处理和 OCR 参数调优显著提升普通文档图片的识别稳定性二、真实问题OCR 不是只调用模型OCR 的识别效果通常由三部分决定图像质量 版面结构 OCR 参数很多时候不是 OCR 引擎不行而是输入图太差。比如分辨率低倾斜阴影背景噪声对比度低字体太小图像压缩严重所以 OCR 工程里预处理比很多人想象得重要。三、架构设计OCR 流程应该拆成五步输入图片 ↓ 方向修正 ↓ 灰度化 去噪 ↓ 二值化 对比度增强 ↓ 版面裁剪 / 倾斜校正 ↓ OCR 识别 ↓ 结果清洗项目结构ocr-preprocess-demo/ ├── app.py ├── ocr/ │ ├── preprocess.py │ ├── deskew.py │ ├── recognize.py │ └── cleanup.py └── outputs/四、环境准备安装 Tesseract。Windows 需要先安装 Tesseract OCR并配置环境变量。Python 依赖pipinstallopencv-python4.9.0.80pillow10.3.0pytesseract0.3.10numpy1.26.4确认命令可用tesseract--version五、基础 OCR 识别代码importpytesseractfromPILimportImagedefrecognize_raw(image_path:str,langeng):imageImage.open(image_path)returnpytesseract.image_to_string(image,langlang)print(recognize_raw(input.jpg,langeng))如果识别中文需要安装中文语言包并使用langchi_sim中英文混合langchi_simeng六、图像预处理灰度化、去噪、二值化创建ocr/preprocess.py代码importcv2importnumpyasnpdefpreprocess_for_ocr(image_path:str,output_path:str|NoneNone):imagecv2.imread(image_path)ifimageisNone:raiseRuntimeError(fcannot read image:{image_path})graycv2.cvtColor(image,cv2.COLOR_BGR2GRAY)# 放大图片小字 OCR 会更稳graycv2.resize(gray,None,fx2,fy2,interpolationcv2.INTER_CUBIC)# 轻度去噪denoisedcv2.medianBlur(gray,3)# 自适应二值化适合光照不均文档binarycv2.adaptiveThreshold(denoised,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,31,11)ifoutput_path:cv2.imwrite(output_path,binary)returnbinary测试fromocr.preprocessimportpreprocess_for_ocr preprocess_for_ocr(input.jpg,outputs/preprocessed.png)七、倾斜校正文档稍微倾斜OCR 效果会明显下降。创建ocr/deskew.py代码importcv2importnumpyasnpdefdeskew(binary_image): 对二值图进行简单倾斜校正。 coordsnp.column_stack(np.where(binary_image255))iflen(coords)0:returnbinary_image anglecv2.minAreaRect(coords)[-1]ifangle-45:angle-(90angle)else:angle-angle h,wbinary_image.shape[:2]center(w//2,h//2)matrixcv2.getRotationMatrix2D(center,angle,1.0)rotatedcv2.warpAffine(binary_image,matrix,(w,h),flagscv2.INTER_CUBIC,borderModecv2.BORDER_REPLICATE)returnrotated使用importcv2fromocr.preprocessimportpreprocess_for_ocrfromocr.deskewimportdeskew binarypreprocess_for_ocr(input.jpg)fixeddeskew(binary)cv2.imwrite(outputs/deskew.png,fixed)八、OCR 参数调优Tesseract 有一个非常重要的参数--psm常用模式6单个文本块 7单行文本 11稀疏文本 13原始行封装识别函数importpytesseractfromPILimportImagedefrecognize_image(image,langeng,psm6):configf--oem 3 --psm{psm}ifnotisinstance(image,Image.Image):imageImage.fromarray(image)returnpytesseract.image_to_string(image,langlang,configconfig)不同场景建议整页文档psm 6 单行验证码式文本psm 7 截图零散文字psm 11 表格单元格psm 7 或 13九、结果清洗创建ocr/cleanup.py代码importredefclean_ocr_text(text:str)-str:linestext.splitlines()cleaned[]forlineinlines:lineline.strip()ifnotline:continue# 合并多余空格linere.sub(r\s, ,line)cleaned.append(line)return\n.join(cleaned)十、完整主程序创建app.pyimportargparseimportcv2fromocr.preprocessimportpreprocess_for_ocrfromocr.deskewimportdeskewfromocr.recognizeimportrecognize_imagefromocr.cleanupimportclean_ocr_textdefmain():parserargparse.ArgumentParser()parser.add_argument(--image,requiredTrue)parser.add_argument(--lang,defaulteng)parser.add_argument(--psm,typeint,default6)argsparser.parse_args()binarypreprocess_for_ocr(args.image,outputs/preprocessed.png)fixeddeskew(binary)cv2.imwrite(outputs/deskew.png,fixed)textrecognize_image(fixed,langargs.lang,psmargs.psm)textclean_ocr_text(text)print(text)if__name____main__:main()运行python app.py--imageinput.jpg--langeng--psm6中文python app.py--imageinput.jpg--langchi_simeng--psm6十一、验证结果不要只看输出有没有文字。建议对比原图 OCR 结果 预处理后 OCR 结果 预处理 倾斜校正结果 不同 psm 的结果可以保存到文件withopen(outputs/result.txt,w,encodingutf-8)asf:f.write(text)如果有标准答案可以计算字符准确率。简单示例defchar_accuracy(pred:str,gt:str):totalmax(len(gt),1)samesum(1fora,binzip(pred,gt)ifab)returnsame/total十二、踩坑记录坑 1图片太小直接 OCR小字建议先放大 2 倍。cv2.resize(gray,None,fx2,fy2)坑 2二值化参数固定普通阈值cv2.threshold(gray,127,255,cv2.THRESH_BINARY)对光照不均很差。文档图建议用自适应阈值。坑 3没有安装语言包识别中文需要chi_sim。否则会乱码或完全识别不出来。坑 4PSM 用错整页文档用单行模式识别肯定差。要根据版面选择 PSM。十三、适合收藏OCR 预处理流程1. 读取图片 2. EXIF 方向修正 3. 灰度化 4. 放大 1.5 到 2 倍 5. 中值滤波去噪 6. 自适应二值化 7. 倾斜校正 8. 设置合适 psm 9. OCR 识别 10. 文本清洗十四、避坑清单1. 不要直接拿原图 OCR 2. 不要忽略图片分辨率 3. 不要所有图片都用同一个 psm 4. 不要忽略倾斜问题 5. 不要过度降噪导致文字断裂 6. 不要用普通阈值处理复杂光照 7. 不要忘记安装语言包 8. 不要只看识别结果要保存预处理图排查十五、总结与优化建议OCR 系统的效果很大程度取决于图像预处理。工程建议保存每一步中间图对不同文档类型设置不同预处理策略PSM 参数要按场景调识别后要做文本清洗如果业务重要要构建标注集评估准确率后续优化方向1. 接入 PaddleOCR 2. 增加表格结构识别 3. 增加版面检测 4. 使用深度学习文字检测模型 5. 引入纠错词典 6. 对扫描件做阴影去除OCR 不是一个函数调用而是一个完整影像理解管线。