基于PyTorch的验证码识别系统实现

本文介绍如何使用Python和PyTorch构建一个图像验证码识别系统,从数据生成到模型训练与测试,覆盖完整流程。

  1. 安装依赖
    确保安装以下Python库:
    pip install torch torchvision pillow captcha numpy2. 生成验证码数据
    使用​​captcha​​库生成自定义验证码图片:
    from captcha.image import ImageCaptcha
    import random
    import string
    import os
    更多内容访问ttocr.com或联系1436423940
    characters = string.digits + string.ascii_uppercase
    captcha_length = 4
    image_width = 160
    image_height = 60

def generate_captchas(count=10000, output_dir="captchas"):
os.makedirs(output_dir, exist_ok=True)
generator = ImageCaptcha(width=image_width, height=image_height)
for i in range(count):
text = ''.join(random.choices(characters, k=captcha_length))
image = generator.generate_image(text)
image.save(os.path.join(output_dir, f"{text}_{i}.png"))

generate_captchas()3. 创建数据集类
定义自定义Dataset类以便加载验证码数据:
from torch.utils.data import Dataset, DataLoader
from torchvision import transforms
from PIL import Image
import torch

class CaptchaDataset(Dataset):
def init(self, data_folder):
self.data_folder = data_folder
self.file_list = os.listdir(data_folder)
self.transform = transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.5,), (0.5,))
])
self.char_to_idx = {char: idx for idx, char in enumerate(characters)}

def __len__(self):
    return len(self.file_list)

def __getitem__(self, index):
    filename = self.file_list[index]
    label_str = filename.split('_')[0]
    image = Image.open(os.path.join(self.data_folder, filename)).convert('RGB')
    image = self.transform(image)
    label = torch.tensor([self.char_to_idx[c] for c in label_str], dtype=torch.long)
    return image, label

dataset = CaptchaDataset("captchas")
train_loader = DataLoader(dataset, batch_size=64, shuffle=True)4. 搭建模型结构
使用CNN和双向LSTM结合处理图像特征和字符序列:
import torch.nn as nn

class CaptchaRecognizer(nn.Module):
def init(self):
super().init()
self.cnn = nn.Sequential(
nn.Conv2d(3, 32, kernel_size=3, padding=1), nn.ReLU(), nn.MaxPool2d(2),
nn.Conv2d(32, 64, kernel_size=3, padding=1), nn.ReLU(), nn.MaxPool2d(2),
nn.Conv2d(64, 128, kernel_size=3, padding=1), nn.ReLU(),
nn.MaxPool2d((2, 1))
)
self.rnn = nn.LSTM(128*7, 128, bidirectional=True, num_layers=2, batch_first=True)
self.fc = nn.Linear(256, len(characters))

def forward(self, x):
    x = self.cnn(x)
    x = x.permute(0, 3, 1, 2)
    batch, width, channels, height = x.size()
    x = x.reshape(batch, width, channels * height)
    x, _ = self.rnn(x)
    x = self.fc(x)
    return x5. 训练模型

配置训练流程,包括优化器和损失函数:
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
model = CaptchaRecognizer().to(device)
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)
criterion = nn.CrossEntropyLoss()

for epoch in range(20):
model.train()
running_loss = 0
for images, labels in train_loader:
images, labels = images.to(device), labels.to(device)
outputs = model(images)
loss = sum(criterion(outputs[:, i, :], labels[:, i]) for i in range(captcha_length))
optimizer.zero_grad()
loss.backward()
optimizer.step()
running_loss += loss.item()
print(f"Epoch {epoch+1}, Loss: {running_loss:.4f}")6. 验证和测试
预测验证码图片内容:
def predict(model, img_path):
model.eval()
transform = transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.5,), (0.5,))
])
img = Image.open(img_path).convert('RGB')
img = transform(img).unsqueeze(0).to(device)
with torch.no_grad():
output = model(img)
prediction = torch.argmax(output, dim=2)
predicted_text = ''.join([characters[i] for i in prediction[0]])
return predicted_text

test_img_path = "captchas/7XK2_0.png"
predicted = predict(model, test_img_path)
print("Predicted:", predicted)

posted @ 2025-04-27 12:38  ttocr、com  阅读(23)  评论(0)    收藏  举报