Python多通道特征融合的验证码识别系统

验证码识别是图像分类和OCR技术的交叉领域,具有一定的挑战性。本文提出一种结合多通道特征提取的轻量化神经网络模型,利用Python与PyTorch实现图像验证码识别。系统包含数据生成、图像预处理、模型构建、训练测试等完整流程,实验证明该方法在多种变形验证码数据集上具有较高的识别准确率。

一、研究背景
验证码广泛用于防止恶意爬虫和暴力攻击,其复杂性给自动化识别带来了挑战。传统方法依赖图像分割与字符分类,而基于深度学习的端到端识别则有效解决了字符连接、干扰线等问题。本文基于多尺度卷积融合思想,设计并实现一种轻量化网络结构,提升验证码识别效果。

二、数据生成与预处理
我们使用 captcha 库生成长度为4-6位的英文数字混合验证码。预处理包括灰度化、标准化、尺寸调整等操作。

from captcha.image import ImageCaptcha
from PIL import Image
import random, os, string

def generate_data(output_dir, count):
os.makedirs(output_dir, exist_ok=True)
chars = string.digits + string.ascii_uppercase
generator = ImageCaptcha(width=160, height=60)
for _ in range(count):
text = ''.join(random.choices(chars, k=random.randint(4, 6)))
img = generator.generate_image(text)
img.save(os.path.join(output_dir, f"{text}.png"))

generate_data("data/train", 4000)
generate_data("data/test", 500)
预处理示例:

from torchvision import transforms

transform = transforms.Compose([
transforms.Grayscale(),
transforms.Resize((60, 160)),
transforms.ToTensor(),
transforms.Normalize((0.5,), (0.5,))
])
三、网络模型设计:多尺度卷积融合结构
本模型结合不同感受野的卷积核提取特征,再融合通道信息,提高模型鲁棒性。

import torch.nn as nn

class MultiScaleCNN(nn.Module):
def init(self, num_classes=36, length=5):
super().init()
self.branch3 = nn.Conv2d(1, 16, kernel_size=3, padding=1)
self.branch5 = nn.Conv2d(1, 16, kernel_size=5, padding=2)
self.branch7 = nn.Conv2d(1, 16, kernel_size=7, padding=3)
self.pool = nn.MaxPool2d(2, 2)
self.fc = nn.Sequential(
nn.Linear(16*3 * 30 * 80, 512),
nn.ReLU(),
nn.Linear(512, length * num_classes)
)

def forward(self, x):
    x3 = self.pool(nn.ReLU()(self.branch3(x)))
    x5 = self.pool(nn.ReLU()(self.branch5(x)))
    x7 = self.pool(nn.ReLU()(self.branch7(x)))
    x = torch.cat([x3, x5, x7], dim=1)
    x = x.view(x.size(0), -1)
    x = self.fc(x)
    return x.view(-1, 5, 36)

四、标签编码与解码

import string
import torch

all_chars = string.digits + string.ascii_uppercase
char2idx = {ch: idx for idx, ch in enumerate(all_chars)}
idx2char = {idx: ch for ch, idx in char2idx.items()}

def encode_label(text, maxlen=5):
text = text.ljust(maxlen, '#') # padding
return [char2idx.get(ch, 0) for ch in text]

def decode_label(indices):
return ''.join(idx2char[i] for i in indices if i < len(idx2char))
五、模型训练

import torch.optim as optim
import torch.nn.functional as F

def train(model, dataloader, optimizer, device):
model.train()
for imgs, labels in dataloader:
imgs, labels = imgs.to(device), labels.to(device)
output = model(imgs)
loss = sum(F.cross_entropy(output[:, i, :], labels[:, i]) for i in range(5))
optimizer.zero_grad()
loss.backward()
optimizer.step()

posted @ 2025-08-05 11:45  ttocr、com  阅读(14)  评论(0)    收藏  举报