遍历边界框坐标提取ROI文本时Pytesseract无输出问题求解
多边界框OCR识别无输出修复方案
问题场景
需遍历两组边界框坐标提取框内文本,示例坐标为928 271 68 16、1039 271 48 16,OpenCV可正常弹窗展示对应ROI区域,但Pytesseract调用后无任何文本输出。
原有坐标存储代码
# get x, y, w, h coordinates in lists for zipping. x_coor = [item for item in roi[0]] y_coor = [item for item in roi[1]] w_coor = [item for item in roi[2]] h_coor = [item for item in roi[3]]
原有循环识别代码
for x, y, w, h in zip(x_coor, y_coor, w_coor, h_coor): # print(x, y, w, h) ROI = img[y:y + h, x:x + w] cv.imshow("Detected ROI", ROI) cv.waitKey(0) upi_string = pytesseract.image_to_string(ROI) upi_roi = upi_string.lower() print(upi_roi)
修复步骤
- 统一坐标类型
OpenCV数组切片要求索引为非负整数,若读取到的坐标为浮点数、字符串类型,会导致ROI数据格式异常:imshow可兼容异常格式显示,但Pytesseract无法识别非法图像矩阵,直接返回空字符串。坐标存储阶段统一做类型转换:
x_coor = [int(item) for item in roi[0]] y_coor = [int(item) for item in roi[1]] w_coor = [int(item) for item in roi[2]] h_coor = [int(item) for item in roi[3]]
- 增加ROI边界校验
防止坐标为负、宽高为0导致切片越界报错或生成空矩阵:
for x, y, w, h in zip(x_coor, y_coor, w_coor, h_coor): x = max(0, x) y = max(0, y) w = max(1, w) h = max(1, h) ROI = img[y:y+h, x:x+w]
- 补充小尺寸ROI预处理
示例中边界框高度仅16px,远低于Pytesseract最优识别尺寸(字符高度建议≥30px),直接识别会将内容判定为噪声返回空结果,识别前做灰度、放大、二值化处理:
# 转灰度图 gray_roi = cv.cvtColor(ROI, cv.COLOR_BGR2GRAY) # 3倍放大适配识别尺寸 scale_roi = cv.resize(gray_roi, None, fx=3, fy=3, interpolation=cv.INTER_CUBIC) # OTSU自动阈值二值化,提升对比度 _, binary_roi = cv.threshold(scale_roi, 0, 255, cv.THRESH_BINARY + cv.THRESH_OTSU)
- 配置Pytesseract识别参数
默认识别模式为整页分割,单行小文本需指定psm参数,未配置环境变量时需显式指定tesseract路径:
# 若tesseract未加入系统环境变量,取消下一行注释并替换为本地安装路径 # pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract.exe' # --psm 7 表示将输入图像视为单行文本 upi_string = pytesseract.image_to_string(binary_roi, lang='eng', config='--psm 7') # 去除识别结果首尾的换行、空格 upi_roi = upi_string.strip().lower() print(upi_roi) # 所有窗口展示结束后销毁窗口 cv.destroyAllWindows()
完整可用代码
import cv2 as cv import pytesseract # 坐标读取与类型转换 x_coor = [int(item) for item in roi[0]] y_coor = [int(item) for item in roi[1]] w_coor = [int(item) for item in roi[2]] h_coor = [int(item) for item in roi[3]] # 按需配置tesseract路径 # pytesseract.pytesseract.tesseract_cmd = r'本地tesseract.exe路径' for x, y, w, h in zip(x_coor, y_coor, w_coor, h_coor): # 边界校验 x = max(0, x) y = max(0, y) w = max(1, w) h = max(1, h) # 截取ROI ROI = img[y:y + h, x:x + w] # 预处理 gray_roi = cv.cvtColor(ROI, cv.COLOR_BGR2GRAY) scale_roi = cv.resize(gray_roi, None, fx=3, fy=3, interpolation=cv.INTER_CUBIC) _, binary_roi = cv.threshold(scale_roi, 0, 255, cv.THRESH_BINARY + cv.THRESH_OTSU) # 可视化 cv.imshow("Detected ROI", binary_roi) cv.waitKey(0) # OCR识别 upi_string = pytesseract.image_to_string(binary_roi, lang='eng', config='--psm 7') upi_roi = upi_string.strip().lower() print(upi_roi) cv.destroyAllWindows()
内容的提问来源于stack exchange,提问作者KskiAl
相关产品推荐
相关产品推荐

