验证码识别极简实战:200行Python代码从零实现

本文将带你用最少量的代码实现一个完整的验证码识别系统,无需复杂架构,直接运行即可看到效果。

  1. 环境准备(只需3个库)
    bash
    pip install tensorflow opencv-python pillow
  2. 完整实现代码(captcha_recognizer.py)
    python
    import cv2
    import numpy as np
    from PIL import Image, ImageDraw, ImageFont
    import random
    import string
    from tensorflow import keras
    from tensorflow.keras import layers
    更多内容访问ttocr.com或联系1436423940

配置参数

CHARACTERS = string.digits + string.ascii_uppercase # 识别字符集
CAPTCHA_LENGTH = 5 # 验证码长度
IMAGE_WIDTH, IMAGE_HEIGHT = 180, 60 # 图片尺寸

1. 验证码生成器

def generate_captcha(text=None):
"""生成单张验证码图片"""
text = text or ''.join(random.choices(CHARACTERS, k=CAPTCHA_LENGTH))
img = Image.new('RGB', (IMAGE_WIDTH, IMAGE_HEIGHT), (255, 255, 255))
draw = ImageDraw.Draw(img)

# 使用系统默认字体
font = ImageFont.load_default()

# 绘制每个字符(带随机位置和旋转)
x_pos = 10
for char in text:
    y_pos = random.randint(5, IMAGE_HEIGHT-30)
    angle = random.randint(-20, 20)
    
    # 单独绘制每个字符以实现旋转
    char_img = Image.new('RGBA', (30, 30), (0, 0, 0, 0))
    char_draw = ImageDraw.Draw(char_img)
    char_draw.text((0, 0), char, font=font, fill=(0, 0, 0))
    char_img = char_img.rotate(angle, expand=1)
    
    img.paste(char_img, (x_pos, y_pos), char_img)
    x_pos += 30 + random.randint(-5, 5)

# 添加干扰线
for _ in range(3):
    x1, y1 = random.randint(0, IMAGE_WIDTH), random.randint(0, IMAGE_HEIGHT)
    x2, y2 = random.randint(0, IMAGE_WIDTH), random.randint(0, IMAGE_HEIGHT)
    draw.line([(x1, y1), (x2, y2)], 
             fill=(random.randint(0, 200), random.randint(0, 200), random.randint(0, 200)), 
             width=1)

return text, np.array(img)

2. 创建数据集

def create_dataset(sample_count=1000):
"""生成训练数据集"""
X = np.zeros((sample_count, IMAGE_HEIGHT, IMAGE_WIDTH, 1), dtype=np.float32)
y = np.zeros((sample_count, CAPTCHA_LENGTH), dtype=np.uint8)

char_to_index = {c:i for i,c in enumerate(CHARACTERS)}

for i in range(sample_count):
    text, img = generate_captcha()
    gray_img = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
    X[i] = np.expand_dims(gray_img / 255.0, axis=-1)
    y[i] = [char_to_index[c] for c in text]

return X, y

3. 构建CNN模型

def build_model():
"""构建简单的CNN模型"""
model = keras.Sequential([
layers.Conv2D(32, (3,3), activation='relu', input_shape=(IMAGE_HEIGHT, IMAGE_WIDTH, 1)),
layers.MaxPooling2D((2,2)),
layers.Conv2D(64, (3,3), activation='relu'),
layers.MaxPooling2D((2,2)),
layers.Flatten(),
layers.Dense(128, activation='relu'),
layers.Dense(len(CHARACTERS)*CAPTCHA_LENGTH, activation='softmax'),
layers.Reshape((CAPTCHA_LENGTH, len(CHARACTERS)))
])

model.compile(optimizer='adam',
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])
return model

4. 训练与评估

def train_model():
# 生成数据
X, y = create_dataset(2000) # 2000个样本
X_train, X_test = X[:1500], X[1500:]
y_train, y_test = y[:1500], y[1500:]

# 构建并训练模型
model = build_model()
model.fit(X_train, y_train, 
          validation_data=(X_test, y_test),
          epochs=30,
          batch_size=32)

return model

5. 预测函数

def predict_captcha(model, image_path):
"""预测验证码"""
img = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)
img = cv2.resize(img, (IMAGE_WIDTH, IMAGE_HEIGHT))
img = np.expand_dims(img / 255.0, axis=(0, -1))

pred = model.predict(img)
captcha = ''.join([CHARACTERS[i] for i in np.argmax(pred[0], axis=1)])
return captcha

主程序

if name == 'main':
# 训练模型
print("正在训练模型...")
model = train_model()

# 测试预测
test_text, test_img = generate_captcha()
cv2.imwrite('test_captcha.png', cv2.cvtColor(test_img, cv2.COLOR_RGB2BGR))

predicted = predict_captcha(model, 'test_captcha.png')
print(f"\n测试验证码: {test_text}")
print(f"识别结果: {predicted}")
print(f"准确率: {sum(t == p for t,p in zip(test_text, predicted))/CAPTCHA_LENGTH:.0%}")
  1. 代码使用说明
    将代码保存为captcha_recognizer.py

安装依赖:pip install tensorflow opencv-python pillow

直接运行:python captcha_recognizer.py

  1. 代码执行流程
    自动生成训练数据:创建2000张验证码图片(内存中生成,不保存到磁盘)

训练CNN模型:30个epoch的训练过程

测试识别效果:随机生成一张测试验证码并尝试识别

posted @ 2025-05-18 13:05  ttocr、com  阅读(51)  评论(0)    收藏  举报