如何通过OpenCV预处理文档图像提升Pytesseract文本提取效果(针对右侧数字识别不佳问题)
如何通过OpenCV预处理文档图像提升Pytesseract文本提取效果(针对右侧数字识别不佳问题)
Hey there! 看了你当前的代码和识别结果,确实右侧表格里的数字识别得乱七八糟——这主要是因为你的预处理步骤还不够针对性,没解决文档图像里的噪声、对比度不足、字符边缘模糊这些核心问题,尤其是表格区域的数字本身偏细,和背景的区分度本来就弱,简单的灰度+1x1核膨胀腐蚀根本起不到作用。
我给你整理了一套针对性的改进方案,一步步来优化:
核心改进思路
- 自适应阈值替代简单灰度化:普通灰度化没法应对文档里的不均匀光照、阴影,自适应阈值能根据局部区域亮度自动调整,把字符和背景彻底分开
- 针对性形态学操作:换掉没用的1x1核,用匹配数字形态的小核强化字符边缘,同时去除噪声
- 提前降噪:扫描/拍摄的文档总有斑点噪声,先降噪能让Tesseract更容易抓住字符轮廓
- 优化Tesseract配置:调整PSM模式和引擎参数,更适配表格类文本
调整后的完整代码
import cv2 import numpy as np import pytesseract path = '1.jpg' # 读取图像并放大(你原来的插值方法没问题,保留) img = cv2.imread(path) img = cv2.resize(img, None, fx=1.8, fy=1.8, interpolation=cv2.INTER_CUBIC) # 转灰度后先降噪:高斯模糊去除细斑点噪声 gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) blurred = cv2.GaussianBlur(gray, (3, 3), 0) # 自适应阈值二值化:把文本转为黑字白底(用INV是因为Tesseract更适配黑字白底) # blockSize选奇数,代表局部计算阈值的区域大小;C是减去的常数,调整对比度 thresh = cv2.adaptiveThreshold(blurred, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 11, 2) # 形态学操作:用横向小核膨胀,强化数字这类窄长字符的边缘 kernel = np.ones((2, 1), np.uint8) processed_img = cv2.dilate(thresh, kernel, iterations=1) # 可选:如果还有边缘噪声,做一次腐蚀去除 processed_img = cv2.erode(processed_img, kernel, iterations=1) # 优化Tesseract配置: # --oem 3 使用默认OCR引擎;--psm 6 假设每行是单一文本块,适配表格行 # 保留你的字符白名单,确保只识别需要的内容 custom_config = r'--oem 3 --psm 6 -c preserve_interword_spaces=1 -c tessedit_char_whitelist=0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ* ' text = str(pytesseract.image_to_string(processed_img, lang='eng', config=custom_config)) print(text)
额外调试建议
- 如果数字还是识别不准,可以尝试调整自适应阈值的
blockSize(比如改成13、15)和C值(比如改成3、4),观察预处理后的图像效果 - 要是字符依然模糊,把放大比例
fx/fy调到2.0试试 - 对于有明显表格线的文档,可以先检测并去除表格线,避免线条干扰数字识别
备注:内容来源于stack exchange,提问作者MKROSTM




