英文验证码识别成功率低因默认PSM=3不适用,须改用PSM=8、OTSU二值化、放大图像、显式指定lang='eng'并白名单字符。

直接识别英文验证码成功率通常低于60%,必须配合预处理+PSM配置,否则基本无效。
pytesseract.image_to_string() 为什么识别英文验证码总返回空或乱码
常见错误现象:image_to_string() 直接读取原始截图返回空字符串、单个字母、或一堆符号(如 @@@###),不是库没装好,而是 Tesseract 默认按整段印刷体排版解析,而验证码是孤立字符+干扰线的组合。
根本原因在于默认 PSM(Page Segmentation Mode)是 --psm 3(自动检测页面结构),它会尝试找“段落”“行”,但验证码根本没有这些结构。
实操建议:
立即学习“Python免费学习笔记(深入)”;
- 强制指定
--psm 8:将图像视为单个单词(single word),适用于 4–6 位英文/数字组合 - 禁用字典检查:
--oem 3(LSTM OCR 引擎)+-c tessedit_char_whitelist=ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789,避免识别出标点或空格 - Windows 用户务必确认
pytesseract.pytesseract.tesseract_cmd指向正确路径,否则静默失败
灰度+二值化预处理的关键阈值怎么选
海外网站验证码常见特征:浅灰背景(#f0f0f0)、深灰字符(#333333)、无粗干扰线但有细噪点。用固定阈值 127 或 140 往往失效。
更可靠的做法是用 OpenCV 的 OTSU 自动阈值:
import cv2
img = cv2.imread('captcha.png', cv2.IMREAD_GRAYSCALE)
_, binary = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
如果 OTSU 结果过白(字符断裂),可手动下调 10–20 点;过黑(背景残留),则上调。实际中 threshold = 110 在多数欧美站点验证码上表现稳定。
注意:Image.convert('1') 不推荐——它用固定 127 阈值且不支持灰度前置,对低对比度图极易全黑或全白。
为什么加了 --psm 8 还是识别不准?检查这三点
即使参数和预处理都对,仍可能失败。排查顺序如下:
- 确认图像尺寸:Tesseract 对小于 20px 高的字符识别极差,用
cv2.resize(binary, None, fx=2, fy=2)放大 2 倍再传入 - 检查字符是否粘连:用
cv2.morphologyEx(binary, cv2.MORPH_CLOSE, kernel)轻微闭运算(kernel = np.ones((1,2),np.uint8))连接断笔,但别过度,否则字母 o 和 e 会糊成一团 - 验证语言包:英文识别必须带
lang='eng',即使系统默认也是 eng,显式声明可避免加载失败静默回退到空结果
真正卡住的地方往往不是代码写错,而是同一套参数在 A 站有效、B 站失效——因为每个海外网站生成验证码的字体、抗锯齿强度、背景透明度都不同。每次换站,先用 cv2.imshow() 看一眼二值化后效果,比调十次 image_to_string() 更省时间。


















