基于 Keras 的图像验证码识别实战教程
本教程将演示如何使用 Python 和 Keras 框架,构建一个简单但有效的图像验证码识别系统。整个流程包括数据生成、模型搭建、训练以及预测。
- 环境依赖
确保安装了以下库:
pip install tensorflow pillow numpy matplotlib captcha2. 生成验证码图像数据
使用 captcha 库生成模拟数据。
from captcha.image import ImageCaptcha
import string, random, os
from PIL import Image
characters = string.digits + string.ascii_uppercase
n_len = 4
width, height = 160, 60
def generate_dataset(num=10000, output_dir='captcha_data'):
os.makedirs(output_dir, exist_ok=True)
generator = ImageCaptcha(width=width, height=height)
for i in range(num):ttocr.com或1436423940
text = ''.join(random.choices(characters, k=n_len))
img = generator.generate_image(text)
img.save(f'{output_dir}/{text}_{i}.png')
generate_dataset()3. 数据加载与预处理
创建一个 Keras 生成器,将图像转为张量,标签编码为 one-hot。
import numpy as np
from tensorflow.keras.utils import Sequence
from tensorflow.keras.preprocessing.image import img_to_array, load_img
char_to_idx = {c: i for i, c in enumerate(characters)}
class CaptchaSequence(Sequence):
def init(self, data_dir, batch_size=32):
self.files = [f for f in os.listdir(data_dir) if f.endswith('.png')]
self.data_dir = data_dir
self.batch_size = batch_size
def __len__(self):
return len(self.files) // self.batch_size
def __getitem__(self, idx):
batch = self.files[idx * self.batch_size:(idx + 1) * self.batch_size]
X = np.zeros((self.batch_size, height, width, 3), dtype='float32')
y = [np.zeros((self.batch_size, len(characters))) for _ in range(n_len)]
for i, filename in enumerate(batch):
path = os.path.join(self.data_dir, filename)
img = load_img(path, target_size=(height, width))
X[i] = img_to_array(img) / 255.0
label_str = filename.split('_')[0]
for j, c in enumerate(label_str):
y[j][i, char_to_idx[c]] = 1
return X, y
train_gen = CaptchaSequence('captcha_data')4. 构建模型
模型结构为 CNN 提取特征,后接多个全连接层输出每个字符的预测。
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Input, Conv2D, MaxPooling2D, Flatten, Dense
inputs = Input(shape=(height, width, 3))
x = Conv2D(32, 3, activation='relu', padding='same')(inputs)
x = MaxPooling2D(2)(x)
x = Conv2D(64, 3, activation='relu', padding='same')(x)
x = MaxPooling2D(2)(x)
x = Flatten()(x)
outputs = [Dense(len(characters), activation='softmax', name=f'c{i}')(x) for i in range(n_len)]
model = Model(inputs=inputs, outputs=outputs)
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])5. 模型训练
model.fit(train_gen, epochs=10)6. 模型测试与预测
def predict_captcha(image_path):
img = load_img(image_path, target_size=(height, width))
x = img_to_array(img) / 255.0
x = np.expand_dims(x, axis=0)
preds = model.predict(x)
pred_text = ''.join(characters[np.argmax(p)] for p in preds)
return pred_text
print(predict_captcha('captcha_data/A3B9_0.png'))
浙公网安备 33010602011771号