验证码识别极简实战:200行Python代码从零实现
本文将带你用最少量的代码实现一个完整的验证码识别系统,无需复杂架构,直接运行即可看到效果。
- 环境准备(只需3个库)
bash
pip install tensorflow opencv-python pillow - 完整实现代码(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%}")
- 代码使用说明
将代码保存为captcha_recognizer.py
安装依赖:pip install tensorflow opencv-python pillow
直接运行:python captcha_recognizer.py
- 代码执行流程
自动生成训练数据:创建2000张验证码图片(内存中生成,不保存到磁盘)
训练CNN模型:30个epoch的训练过程
测试识别效果:随机生成一张测试验证码并尝试识别
浙公网安备 33010602011771号