基于pytesseract的图像十进制数值识别:HSV阈值与识别错误问题
解决LCD数值识别的HSV通用阈值与Tesseract识别错误问题
一、通用HSV阈值设置方案
固定HSV阈值换图失效,核心原因是不同图像的光照、色彩差异大,试试这些动态调整方法:
- 灰度二值化优先+HSV补充:LCD数字对比度通常很高,先转灰度图用Otsu自动二值化生成基础掩码,再结合HSV过滤背景杂色。Otsu能自动根据图像灰度分布找最优阈值,比硬编码HSV通用得多。
- 动态计算HSV范围:提取图像HSV各通道的均值和标准差,用「均值±1.5~2倍标准差」作为阈值范围,计算后把值限制在HSV合法区间(H:0-179,S/V:0-255),能自动适配不同光照下的图像。
- 预处理优化掩码:先做高斯模糊去噪,再用形态学闭运算(腐蚀+膨胀)填充数字上的小缺口,避免掩码断裂影响后续识别。
二、Tesseract识别错误修正(79.8→75.8)
这种相似字符混淆问题,从预处理和识别配置两方面解决:
- 严格限制字符集:只让Tesseract识别数字和小数点,配置参数用
--psm 7 --oem 3 -c tessedit_char_whitelist=0123456789.,--psm 7指定识别单文本行,减少无关字符干扰。 - 放大+增强对比度:把裁剪后的数字区域放大2~3倍,用CLAHE自适应直方图均衡增强对比度,让数字边缘更清晰,帮助Tesseract区分9和5的形状差异。
- 相似字符规则校验:针对9和5的形状差异写简单判断逻辑,比如9的顶部是封闭的,5的顶部是开放的,提取数字上半部分的像素数量,若像素多则判定为9,替换识别错误的5。
- 训练自定义字库:如果通用方法还是不行,收集一批LCD数字样本,用Tesseract的训练工具生成专用字库,能大幅提升特定场景的识别准确率。
修正后的示例代码
import cv2 import numpy as np import pytesseract def get_dynamic_hsv_range(hsv_img): # 计算HSV各通道均值与标准差 h_mean, h_std = np.mean(hsv_img[:,:,0]), np.std(hsv_img[:,:,0]) s_mean, s_std = np.mean(hsv_img[:,:,1]), np.std(hsv_img[:,:,1]) v_mean, v_std = np.mean(hsv_img[:,:,2]), np.std(hsv_img[:,:,2]) # 生成动态阈值并限制合法范围 lower_hsv = np.clip([h_mean - 1.5*h_std, s_mean - 1.5*s_std, v_mean - 1.5*v_std], 0, [179,255,255]) upper_hsv = np.clip([h_mean + 1.5*h_std, s_mean + 1.5*s_std, v_mean + 1.5*v_std], 0, [179,255,255]) return lower_hsv.astype(np.uint8), upper_hsv.astype(np.uint8) def preprocess_image(img_path): img = cv2.imread(img_path) # 高斯模糊去噪 blur = cv2.GaussianBlur(img, (3,3), 0) # 动态HSV掩码 hsv = cv2.cvtColor(blur, cv2.COLOR_BGR2HSV) lower, upper = get_dynamic_hsv_range(hsv) mask = cv2.inRange(hsv, lower, upper) # 形态学闭运算优化掩码 mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, np.ones((2,2), np.uint8)) # 灰度增强+放大 gray = cv2.bitwise_and(cv2.cvtColor(img, cv2.COLOR_BGR2GRAY), mask) clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8)) gray_enhanced = clahe.apply(gray) enlarged = cv2.resize(gray_enhanced, None, fx=2, fy=2, interpolation=cv2.INTER_CUBIC) # Otsu二值化 _, thresh = cv2.threshold(enlarged, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU) return thresh def recognize_lcd_number(img_path): processed_img = preprocess_image(img_path) # Tesseract自定义配置 custom_config = r'--psm 7 --oem 3 -c tessedit_char_whitelist=0123456789.' text = pytesseract.image_to_string(processed_img, config=custom_config).strip() # 9/5混淆修正示例 if '.' in text and len(text) == 4: # 匹配Xx.x格式 num_part = text[1] if num_part == '5': # 提取数字上半部分像素,判断是否为9 h, w = processed_img.shape top_region = processed_img[:h//3, w//4:w*3//4] if np.sum(top_region) > 1500: # 阈值根据实际图像调整 text = text[:1] + '9' + text[2:] return text # 调用示例 print(recognize_lcd_number('lcd_image.jpg'))
内容的提问来源于stack exchange,提问作者Mansi Sathawane
相关产品推荐
相关产品推荐

