用 Keras 和深度学习实现验证码识别

在本篇文章中,我们将介绍如何利用 Keras(基于 TensorFlow 的高级深度学习框架)实现一个验证码识别系统。通过构建一个简单的卷积神经网络(CNN),我们可以有效地从验证码图像中识别出字符。CNN 在图像识别任务中非常有效,尤其适用于验证码识别这一任务。

  1. 环境准备
    首先,确保你已经安装了以下必要的库:

pip install keras tensorflow opencv-python numpy matplotlib pillow
keras:高层次的深度学习API,基于TensorFlow。

tensorflow:深度学习框架。

opencv-python:用于图像处理。

numpy:用于数组处理和计算。

matplotlib:用于可视化。

pillow:用于图像加载和预处理。

  1. 数据集准备与图像预处理
    我们假设你已经有一个包含验证码图像的文件夹。为了进行训练,我们需要对这些图像进行预处理,包括:灰度化、二值化、尺寸调整等操作。

(1) 图像预处理函数

import cv2
import numpy as np
import os
from tensorflow.keras.preprocessing.image import img_to_array

def preprocess_image(img_path, img_size=(64, 64)):
# 读取图像
img = cv2.imread(img_path)

# 转换为灰度图
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# 二值化处理
_, binary = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)

# 调整图像大小
resized_img = cv2.resize(binary, img_size)

# 归一化处理
normalized_img = resized_img / 255.0

# 转换为数组
img_array = img_to_array(normalized_img)

return img_array

示例图像路径

img_path = 'captcha_images/test1.png'
processed_img = preprocess_image(img_path)

显示预处理后的图像

import matplotlib.pyplot as plt
plt.imshow(processed_img, cmap='gray')
plt.show()
在这个函数中,我们对图像进行了灰度化、二值化、尺寸调整和归一化。处理后,我们将图像转换为 NumPy 数组并准备好输入模型。

  1. 标签编码与数据准备
    验证码标签通常由多个字符组成。在本示例中,我们假设验证码只包含数字和字母。我们将对标签进行 One-hot 编码,以便将其传递给神经网络模型。

(1) 标签编码

from tensorflow.keras.utils import to_categorical
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelEncoder

假设验证码包括0-9和A-Z(总共36个字符)

def encode_labels(labels, num_classes=36):
label_encoder = LabelEncoder()
labels_encoded = label_encoder.fit_transform(labels)
labels_onehot = to_categorical(labels_encoded, num_classes=num_classes)
return labels_onehot, label_encoder

读取图像数据和标签

def load_data(image_dir, img_size=(64, 64)):
images = []
labels = []
for filename in os.listdir(image_dir):
if filename.endswith('.png'):
img_path = os.path.join(image_dir, filename)
img = preprocess_image(img_path, img_size)
images.append(img)

        # 提取标签
        label = filename.split('.')[0]
        labels.append(label)

images = np.array(images)
labels = np.array(labels)

# 对标签进行One-hot编码
labels_onehot, label_encoder = encode_labels(labels)

return images, labels_onehot, label_encoder

加载数据集

image_dir = 'captcha_images'
X, y, label_encoder = load_data(image_dir)
这里,我们定义了一个 encode_labels 函数来进行标签的 One-hot 编码,并返回编码后的标签及标签编码器。接着,我们加载了图像数据并对每张图像的标签进行了编码。

  1. 构建卷积神经网络(CNN)
    现在,我们来构建卷积神经网络(CNN)模型。CNN 是图像处理的基础,它通过卷积层自动提取图像中的特征,从而实现分类任务。

(1) 定义 CNN 模型

from tensorflow.keras import layers, models

def build_cnn_model(input_shape=(64, 64, 1), num_classes=36):
model = models.Sequential()

# 第一层卷积层
model.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=input_shape))
model.add(layers.MaxPooling2D((2, 2)))

# 第二层卷积层
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))

# 扁平化层
model.add(layers.Flatten())

# 全连接层
model.add(layers.Dense(128, activation='relu'))

# 输出层
model.add(layers.Dense(num_classes, activation='softmax'))

# 编译模型
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])

return model

构建CNN模型

model = build_cnn_model()

查看模型架构

model.summary()
在这个模型中,我们使用了两层卷积层,每个卷积层后跟一个最大池化层。最后,我们添加了一个全连接层和一个输出层(采用 Softmax 激活函数)来进行多类分类。模型使用 Adam 优化器,并采用 交叉熵损失函数。

  1. 训练模型
    接下来,我们开始训练卷积神经网络。我们将数据集分成训练集和验证集,并使用训练集进行模型训练。

(1) 训练模型

拆分训练集和测试集

from sklearn.model_selection import train_test_split
X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.2, random_state=42)

训练模型

history = model.fit(X_train, y_train, epochs=10, batch_size=32, validation_data=(X_val, y_val))

绘制训练过程中的准确率变化

import matplotlib.pyplot as plt

plt.plot(history.history['accuracy'], label='accuracy')
plt.plot(history.history['val_accuracy'], label='val_accuracy')
plt.xlabel('Epoch')
plt.ylabel('Accuracy')
plt.legend(loc='lower right')
plt.show()
这段代码会训练模型并绘制出训练过程中的准确率变化曲线。通过这些图表,我们可以观察到训练过程中模型表现的变化。

  1. 模型评估与测试
    训练完成后,我们需要对模型的性能进行评估。我们可以在验证集上计算准确率,并评估模型的泛化能力。

(1) 评估模型

评估模型在测试集上的表现

test_loss, test_acc = model.evaluate(X_val, y_val)
print(f"验证集上的损失: {test_loss:.4f}")
print(f"验证集上的准确率: {test_acc:.4f}")
通过这段代码,我们可以获得模型在验证集上的损失和准确率,评估其表现如何。

  1. 对新图像进行预测
    最后,我们可以利用训练好的模型对新图像进行预测。

(1) 进行预测

def predict_captcha(model, img_path, label_encoder):
img = preprocess_image(img_path)

# 扩展维度并进行预测
img = np.expand_dims(img, axis=0)  # 增加批量维度
prediction = model.predict(img)

# 获取预测标签
predicted_label_encoded = np.argmax(prediction, axis=1)
predicted_label = label_encoder.inverse_transform(predicted_label_encoded)

return predicted_label[0]

预测新的验证码

new_image_path = 'captcha_images/test1.png'
predicted_label = predict_captcha(model, new_image_path, label_encoder)
print(f'预测的验证码是: {predicted_label}')
这段代码将新图像传入训练好的模型进行预测,并输出预测结果。

posted @ 2025-04-05 22:05  ttocr、com  阅读(24)  评论(0)    收藏  举报