使用Pytesseract与OpenCV无法识别彩色框内数字问题求解
问题排查与解决方法
识别失败核心原因
- 预处理流程过于冗余,多次二值化、像素反转操作破坏了数字的边缘特征,最终输出的待识别图像对比度不足、数字边缘毛刺较多,不符合Tesseract的识别要求
- 未对小尺寸数字做适配,Tesseract对过小的字符识别精度极低,同时选用的PSM 13参数针对单行文本,对于单个数字的适配性不如PSM 10
优化方案
1. 自动裁切目标区域
目标区域带彩色边框,直接在HSV色彩空间筛选对应颜色的像素即可定位到框的位置,无需手动裁切,实现代码如下:
import cv2 import numpy as np import pytesseract pytesseract.pytesseract.tesseract_cmd = r'Tesseract-OCR\tesseract.exe' # 读取原图 img = cv2.imread('page_image.jpg') hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) # 此处阈值对应蓝色边框,可根据目标框的实际颜色调整HSV范围 lower_color = np.array([90, 50, 50]) upper_color = np.array([130, 255, 255]) mask = cv2.inRange(hsv, lower_color, upper_color) # 筛选轮廓过滤噪声,获取边框坐标 contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) roi = None for cnt in contours: if cv2.contourArea(cnt) > 100: x, y, w, h = cv2.boundingRect(cnt) # 裁切时留2像素内边距,避免切到边框影响数字识别 roi = img[y+2:y+h-2, x+2:x+w-2] break
2. 简化预处理流程
只保留核心的预处理步骤,避免多余操作破坏数字特征:
# 转灰度后放大3倍,提升小字符的识别精度 roi_gray = cv2.cvtColor(roi, cv2.COLOR_BGR2GRAY) roi_resized = cv2.resize(roi_gray, None, fx=3, fy=3, interpolation=cv2.INTER_CUBIC) # 仅做一次二值化即可 _, roi_thresh = cv2.threshold(roi_resized, 0, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)
3. 调整Tesseract识别参数
单个数字识别选用PSM 10(单字符识别模式),识别准确率更高:
result = pytesseract.image_to_string(roi_thresh, config='--psm 10 --oem 3 -c tessedit_char_whitelist=0123456789') print(result.strip())
效果验证
按照上述流程处理后,放大后的数字特征清晰,可正确识别出目标数字6。
内容的提问来源于stack exchange,提问作者mbronzo
相关产品推荐
相关产品推荐

