极简验证码识别实战代码
- 安装依赖(只需运行一次)
bash
pip install tensorflow==2.8.0 opencv-python pillow numpy matplotlib - 完整可运行代码(保存为captcha_recognition.py)
python
import cv2
import numpy as np
from PIL import Image, ImageDraw, ImageFont
import random
import string
import os
from tensorflow import keras
from tensorflow.keras import layers
更多内容访问ttocr.com或联系1436423940
配置参数
CHAR_SET = string.digits + string.ascii_uppercase # 数字+大写字母
CAPTCHA_LEN = 4 # 验证码长度
IMG_WIDTH, IMG_HEIGHT = 160, 60 # 图片尺寸
FONT_PATH = 'arial.ttf' if os.path.exists('arial.ttf') else None
1. 验证码生成函数
def generate_captcha(text=None):
"""生成单张验证码图片"""
text = text or ''.join(random.choices(CHAR_SET, k=CAPTCHA_LEN))
img = Image.new('RGB', (IMG_WIDTH, IMG_HEIGHT), color=(255, 255, 255))
draw = ImageDraw.Draw(img)
try:
font = ImageFont.truetype(FONT_PATH, 36) if FONT_PATH else ImageFont.load_default()
except:
font = ImageFont.load_default()
# 绘制文本(带随机偏移)
x = 10
for char in text:
y = random.randint(5, IMG_HEIGHT-40)
angle = random.randint(-15, 15)
char_img = Image.new('RGBA', (40, 40), (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, y), char_img)
x += 30 + random.randint(-5, 5)
# 添加干扰线
for _ in range(3):
x1, y1 = random.randint(0, IMG_WIDTH), random.randint(0, IMG_HEIGHT)
x2, y2 = random.randint(0, IMG_WIDTH), random.randint(0, IMG_HEIGHT)
draw.line([(x1, y1), (x2, y2)], fill=(random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)), width=1)
# 添加噪点
for _ in range(100):
img.putpixel((random.randint(0, IMG_WIDTH-1), random.randint(0, IMG_HEIGHT-1)),
(random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)))
return text, np.array(img)
2. 生成数据集
def generate_dataset(size=1000, output_dir='captchas'):
if not os.path.exists(output_dir):
os.makedirs(output_dir)
with open(f'{output_dir}/labels.txt', 'w') as f:
for i in range(size):
text, img = generate_captcha()
cv2.imwrite(f'{output_dir}/{i}_{text}.png', cv2.cvtColor(img, cv2.COLOR_RGB2BGR))
f.write(f'{i}_{text}.png\t{text}\n')
3. 数据加载与预处理
def load_dataset(data_dir='captchas'):
with open(f'{data_dir}/labels.txt') as f:
lines = f.read().splitlines()
images, labels = [], []
char_to_num = {c:i for i,c in enumerate(CHAR_SET)}
for line in lines:
path, text = line.split('\t')
img = cv2.imread(f'{data_dir}/{path}', cv2.IMREAD_GRAYSCALE)
img = cv2.resize(img, (IMG_WIDTH, IMG_HEIGHT))
img = img.astype(np.float32) / 255.0
images.append(np.expand_dims(img, axis=-1))
labels.append([char_to_num[c] for c in text])
return np.array(images), np.array(labels)
4. 构建模型
def build_model():
input_img = layers.Input(shape=(IMG_HEIGHT, IMG_WIDTH, 1))
# CNN部分
x = layers.Conv2D(32, (3,3), activation='relu', padding='same')(input_img)
x = layers.MaxPooling2D((2,2))(x)
x = layers.Conv2D(64, (3,3), activation='relu', padding='same')(x)
x = layers.MaxPooling2D((2,2))(x)
# 转换为序列
x = layers.Reshape(((IMG_WIDTH//4), (IMG_HEIGHT//4)*64))(x)
# RNN部分
x = layers.Bidirectional(layers.LSTM(128, return_sequences=True))(x)
x = layers.Bidirectional(layers.LSTM(64, return_sequences=True))(x)
# 输出层
output = layers.Dense(len(CHAR_SET), activation='softmax')(x)
return keras.Model(inputs=input_img, outputs=output)
5. 训练与评估
def train_and_evaluate():
# 生成数据
generate_dataset(1000)
# 加载数据
X, y = load_dataset()
X_train, X_test = X[:800], X[800:]
y_train, y_test = y[:800], y[800:]
# 构建模型
model = build_model()
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
# 训练
model.fit(X_train, y_train,
validation_data=(X_test, y_test),
epochs=20,
batch_size=32)
# 评估
y_pred = np.argmax(model.predict(X_test), axis=-1)
char_acc = np.mean(y_pred.flatten() == y_test.flatten())
captcha_acc = np.mean(np.all(y_pred == y_test, axis=1))
print(f"\n字符准确率: {char_acc:.2%}")
print(f"验证码准确率: {captcha_acc:.2%}")
return model
6. 预测函数
def predict_captcha(model, image_path):
img = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)
img = cv2.resize(img, (IMG_WIDTH, IMG_HEIGHT))
img = img.astype(np.float32) / 255.0
img = np.expand_dims(img, axis=(0, -1))
pred = model.predict(img)
pred_text = ''.join([CHAR_SET[i] for i in np.argmax(pred[0], axis=-1)])
return pred_text
主程序
if name == 'main':
model = train_and_evaluate()
# 测试预测
test_img = 'captchas/0_ABCD.png' # 替换为你的测试图片路径
if os.path.exists(test_img):
print(f"\n测试图片识别结果: {predict_captcha(model, test_img)}")
else:
print("\n训练完成!使用predict_captcha(model, '图片路径')进行预测")
- 使用说明
将上述代码保存为captcha_recognition.py
安装依赖:pip install tensorflow==2.8.0 opencv-python pillow numpy matplotlib
直接运行:python captcha_recognition.py
浙公网安备 33010602011771号