使用Tesseract识别图像中数字时检测效果不佳的技术求助
问题描述
我在对如下类型的图像进行文本检测时遇到了困难:
目前Tesseract难以将数字与图像内的图表元素区分开,我的目标是识别出所有数字及其对应的位置坐标。
我对该图像运行了如下代码,预期可以在检测到的文本周围标注矩形框:
import cv2 import pytesseract from pytesseract import Output import numpy as np pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract' img = cv2.imread('Temp/VE_cropped.png') kernel = np.ones((2,2),np.uint8) img_processed = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) img_processed = cv2.medianBlur(img_processed,3) img_processed = cv2.threshold(img_processed, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1] img_processed = cv2.dilate(img_processed, kernel, iterations = 1) dict_wordsDetected = pytesseract.image_to_data(img_processed, output_type=Output.DICT) img_processed = cv2.cvtColor(img_processed, cv2.COLOR_GRAY2RGB) n_boxes = len(dict_wordsDetected['text']) for i in range(n_boxes): (x, y, w, h) = (dict_wordsDetected['left'][i] , dict_wordsDetected['top'][i] , dict_wordsDetected['width'][i] , dict_wordsDetected['height'][i]) img_processed = cv2.rectangle(img_processed, (x - 10, y - 10), (x + w + 10, y + h + 10), (0, 0, 255), 2) cv2.imshow("processed", img_processed) cv2.waitKey(0)
代码运行后得到的结果如下:
当前识别效果不符合预期,恳请各位提供可行的解决思路。
解决方案
优化思路
- 调整Tesseract识别参数:调用
image_to_data时新增配置项config='--psm 11 -c tessedit_char_whitelist=0123456789.'。--psm 11为稀疏文本模式,适配图像中零散分布的文本识别场景,白名单配置会直接过滤所有非数字、小数点的识别结果,避免把图表线条误判为字符。 - 优化图像预处理逻辑:现有预处理的膨胀操作容易让数字和邻近的图表细线粘连,建议将单纯的膨胀替换为形态学开运算(先腐蚀再膨胀),可先断开数字和周边细线的连接,再补全数字本身的断点。另外可新增轮廓筛选步骤,提前过滤掉面积过大的图表背景、面积过小的噪点,只保留符合数字宽高比、面积区间的轮廓区域再送入识别。
- 更换适配性更高的识别模型:如果调整后Tesseract效果仍然不符合预期,可以替换为PaddleOCR、EAST这类专门针对场景文本的识别工具,内置的数字识别预训练模型对工业图表类场景的适配性远高于默认Tesseract模型,不需要复杂预处理就能拿到准确的数字内容和对应坐标。
- 增加后处理校验规则:可根据业务场景加规则过滤识别结果,比如该场景下数字都是带小数点的数值,长度、格式不符合的结果直接剔除,重叠度过高的重复识别结果也可以按置信度排序后去重,进一步提升准确率。
优化后代码示例
import cv2 import pytesseract from pytesseract import Output import numpy as np pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract' img = cv2.imread('Temp/VE_cropped.png') kernel = np.ones((2,2),np.uint8) # 优化预处理:替换为开运算,避免数字和图表线条粘连 img_processed = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) img_processed = cv2.medianBlur(img_processed,3) img_processed = cv2.threshold(img_processed, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1] img_processed = cv2.morphologyEx(img_processed, cv2.MORPH_OPEN, kernel, iterations=1) # 新增Tesseract配置,限定识别范围和分割模式 custom_config = r'--psm 11 -c tessedit_char_whitelist=0123456789.' dict_wordsDetected = pytesseract.image_to_data(img_processed, output_type=Output.DICT, config=custom_config) img_processed = cv2.cvtColor(img_processed, cv2.COLOR_GRAY2RGB) n_boxes = len(dict_wordsDetected['text']) for i in range(n_boxes): # 新增过滤规则:空文本、置信度过低的结果直接跳过 text = dict_wordsDetected['text'][i].strip() conf = int(dict_wordsDetected['conf'][i]) if not text or conf < 60: continue (x, y, w, h) = (dict_wordsDetected['left'][i] , dict_wordsDetected['top'][i] , dict_wordsDetected['width'][i] , dict_wordsDetected['height'][i]) img_processed = cv2.rectangle(img_processed, (x - 2, y - 2), (x + w + 2, y + h + 2), (0, 0, 255), 2) cv2.imshow("processed", img_processed) cv2.waitKey(0)
内容的提问来源于stack exchange,提问作者stathamos
相关产品推荐
相关产品推荐

