本文主要实现了两个工作:1.验证码生成   2.Pytorch识别验证码

一. 验证码生成

方法1. 利用PIL库的ImageDraw实现绘图,此法参考博客实现:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Tue Mar 27 15:45:04 2018 @author: lps
""" from PIL import Image, ImageDraw, ImageFont, ImageFilter
import random
import cv2
import numpy as np
import matplotlib.pyplot as plt
path = '/media/lps/python-3.5.2.amd64/Lib/site-packages/matplotlib/mpl-data/fonts/ttf/' # 选择字体
data_path = '/home/lps/yanzm/' # random chr
def rndChar():
return chr(random.randint(65, 90)) # 随机字母 def rndInt():
return str(random.randint(0,9)) # 随机数字 def rndColor():
return (random.randint(64, 255), random.randint(64, 255), random.randint(64, 255)) # 随机颜色 def rndColor2():
return (random.randint(32, 127), random.randint(32, 127), random.randint(32, 127)) # 随机颜色 def gaussian_noise(): # 高斯噪声
mu = 125
sigma = 20
return tuple((np.random.normal(mu, sigma, 3).astype(int))) def rotate(x, angle): # 旋转
M_rotate = cv2.getRotationMatrix2D((x.shape[0]/2, x.shape[1]/2), angle, 1)
x = cv2.warpAffine(x, M_rotate, (x.shape[0], x.shape[1]))
return x width = 180 * 4
height = 180 def gen_image(num): for l in range(num): image = Image.new('RGB', (width, height), (255, 255, 255)) # 先生成一张大图 font = ImageFont.truetype(path+'cmb10.ttf', 36) draw = ImageDraw.Draw(image) # 新的画板 for x in range(0,width):
for y in range(0,height):
draw.point((x, y), fill=rndColor()) label = [] for t in range(4): # 每一张验证码4个数字
numb = rndInt()
draw.text((180 * t + 60+10, 60+10), numb, font=font, fill=rndColor2())
label.append(numb) with open(data_path+"label.txt","a") as f:
for s in label:
f.write(s + ' ')
f.writelines("\n") # 写入label img = image.filter(ImageFilter.GaussianBlur(radius=0.5))
img = np.array(img) img1 = np.array([]) for i in range(0,4):
img0 = img[:, 180*i: 180*i+180] # 提取含有验证码的小图
angle = random.randint(-45, 45)
img0 = rotate(img0, angle) # 对小图随机旋转 if img1.any():
img1 = np.concatenate((img1, img0[60:120, 60:120, :]), axis=1) else:
img1 = img0[60:120, 60:120, :] plt.imsave(data_path+'src/' + str(l)+'.jpg', img1) # 保存结果 if __name__=='__main__':
gen_image(100)

结果大致:

方法2. 利用更专业的库:captcha

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Sun Mar 25 19:06:46 2018 @author: lps
"""
from captcha.image import ImageCaptcha
import numpy as np
#import matplotlib.pyplot as plt
from PIL import Image
import random
import cv2 number = ['','','','','','','','','','']
alphabet = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z']
ALPHABET = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'] data_path = '/home/lps/yanzm/' def random_captcha_text(char_set=number,captcha_size=4): # 可以设置只用来生成数字
captcha_text = []
for i in range(captcha_size):
c = random.choice(char_set)
captcha_text.append(c)
return captcha_text def gen_capthcha_text_and_image(m):
image = ImageCaptcha()
captcha_text = random_captcha_text() # 生成数字
captcha_text = ' '.join(captcha_text) # 生成标签 captcha = image.generate(captcha_text) # image.write(captcha_text,captcha_text+'.jpg') captcha_image = Image.open(captcha)
captcha_image = np.array(captcha_image) with open(data_path+"label.txt","a") as f: # 写入标签
f.write(captcha_text)
f.writelines("\n")
cv2.imwrite(data_path + '/src/'+'%.4d.jpg'%m, captcha_image) # 保存 # return captcha_text,captcha_image if __name__ == '__main__': for m in range(0,5000):
# text,image = gen_capthcha_text_and_image()
gen_capthcha_text_and_image(m) # f = plt.figure()
# ax = f.add_subplot(212)
# ax.text(0.1,0.1,text,ha='center',va='center',transform=ax.transAxes)
# plt.imshow(image)
# plt.show()
#

结果大致:

二. pytorch实现

对于一张验证码来说作为一张单一的图片,每输入一张图片,得到四个数字作为输出,只有4个数字同时预测正确才表示预测正确。所以在每一张图上是四个多二分类器:因为验证码上面的数字为0-9,类似于mnist,只不过此时一张图片对应于4个数字。所以思路很简单,实现如下:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Fri Mar 30 15:46:09 2018 @author: lps
"""
import torch
import torch.nn as nn
import torch.nn.functional as F
from torch.autograd import Variable
import torch.optim as optim
import torchvision.models as models
import torchvision
from torch.utils.data import Dataset, DataLoader
from torchvision import transforms, utils
import matplotlib.pyplot as plt
from PIL import Image
#import pandas as pd
import numpy as np
import os
import copy, time file_path = '/home/lps/yanzm'
BATCH_SIZE = 16
EPOCH = 10 # Load data
class dataset(Dataset): def __init__(self, root_dir, label_file, transform=None): self.root_dir = root_dir
self.label = np.loadtxt(label_file)
self.transform = transform def __getitem__(self, idx): img_name = os.path.join(self.root_dir,'%.4d.jpg'%idx)
image = Image.open(img_name)
labels = self.label[idx,:] # sample = image if self.transform:
image = self.transform(image) return image, labels def __len__(self): return (self.label.shape[0]) data = dataset(file_path+'/src', file_path+'/label.txt',transform=transforms.ToTensor()) dataloader = DataLoader(data, batch_size=BATCH_SIZE, shuffle=True, num_workers=4, drop_last=True) dataset_size = len(data) # Conv network
class ConvNet(nn.Module): def __init__(self):
super(ConvNet, self).__init__()
self.conv =nn.Sequential(
nn.Conv2d(3, 32, kernel_size=4, stride=1, padding=2), # in:(bs,3,60,160)
nn.BatchNorm2d(32),
nn.LeakyReLU(0.2, inplace=True),
nn.MaxPool2d(kernel_size=2), # out:(bs,32,30,80) nn.Conv2d(32, 64, kernel_size=4, stride=1, padding=2),
nn.BatchNorm2d(64),
nn.LeakyReLU(0.2, inplace=True),
nn.MaxPool2d(kernel_size=2), # out:(bs,64,15,40) nn.Conv2d(64, 64, kernel_size=3 ,stride=1, padding=1),
nn.BatchNorm2d(64),
nn.LeakyReLU(0.2, inplace=True),
nn.MaxPool2d(kernel_size=2) # out:(bs,64,7,20)
) self.fc1 = nn.Linear(64*7*20, 500)
self.fc2 = nn.Linear(500,40) def forward(self, x):
x = self.conv(x)
x = x.view(x.size(0), -1) # reshape to (batch_size, 64 * 7 * 30)
output = self.fc1(x)
output = self.fc2(output) return output # Train the net
class nCrossEntropyLoss(torch.nn.Module): def __init__(self, n=4):
super(nCrossEntropyLoss, self).__init__()
self.n = n
self.total_loss = 0
self.loss = nn.CrossEntropyLoss() def forward(self, output, label):
output_t = output[:,0:10]
label = Variable(torch.LongTensor(label.data.cpu().numpy())).cuda()
label_t = label[:,0] for i in range(1, self.n):
output_t = torch.cat((output_t, output[:,10*i:10*i+10]), 0) # 损失的思路是将一张图平均剪切为4张小图即4个多分类,然后再用多分类交叉熵方损失
label_t = torch.cat((label_t, label[:,i]), 0)
self.total_loss = self.loss(output_t, label_t) return self.total_loss def equal(np1,np2): n = 0
for i in range(np1.shape[0]):
if (np1[i,:]==np2[i,:]).all():
n += 1 return n net = ConvNet().cuda()
optimizer = torch.optim.Adam(net.parameters(), lr=0.001)
#loss_func = nn.CrossEntropyLoss()
loss_func = nCrossEntropyLoss() best_model_wts = copy.deepcopy(net.state_dict())
best_acc = 0.0 since = time.time()
for epoch in range(EPOCH): running_loss=0.0
running_corrects=0 for step,(inputs,label) in enumerate(dataloader): pred = torch.LongTensor(BATCH_SIZE,1).zero_()
inputs = Variable(inputs).cuda() # (bs, 3, 60, 240)
label = Variable(label).cuda() # (bs, 4) optimizer.zero_grad() output = net(inputs) # (bs, 40)
loss = loss_func(output, label) for i in range(4):
pre = F.log_softmax(output[:,10*i:10*i+10], dim=1) # (bs, 10)
pred = torch.cat((pred, pre.data.max(1, keepdim=True)[1].cpu()), dim=1) # loss.backward()
optimizer.step() running_loss += loss.data[0] * inputs.size()[0]
running_corrects += equal(pred.numpy()[:,1:], label.data.cpu().numpy().astype(int)) epoch_loss = running_loss / dataset_size
epoch_acc = running_corrects / dataset_size if epoch_acc > best_acc:
best_acc = epoch_acc
best_model_wts = copy.deepcopy(net.state_dict()) if epoch == EPOCH-1:
torch.save(best_model_wts, file_path+'/best_model_wts.pkl') print() time_elapsed = time.time() - since
print('Training complete in {:.0f}m {:.0f}s'.format(
time_elapsed // 60, time_elapsed % 60))
print('Train Loss:{:.4f} Acc: {:.4f}'.format(epoch_loss, epoch_acc))

随机生成5000张图片拿来训练,准确率也会有97%左右。

Pytorch之验证码识别的更多相关文章

  1. 写给程序员的机器学习入门 (八) - 卷积神经网络 (CNN) - 图片分类和验证码识别

    这一篇将会介绍卷积神经网络 (CNN),CNN 模型非常适合用来进行图片相关的学习,例如图片分类和验证码识别,也可以配合其他模型实现 OCR. 使用 Python 处理图片 在具体介绍 CNN 之前, ...

  2. 字符型图片验证码识别完整过程及Python实现

    字符型图片验证码识别完整过程及Python实现 1   摘要 验证码是目前互联网上非常常见也是非常重要的一个事物,充当着很多系统的 防火墙 功能,但是随时OCR技术的发展,验证码暴露出来的安全问题也越 ...

  3. 验证码识别<1>

    1. 引子 前两天访问学校自助服务器()缴纳网费,登录时发现这系统的验证码也太过“清晰”了,突然脑袋里就蹦出一个想法:如果能够自动识别验证码,然后采用暴力破解的方式,那么密码不是可以轻易被破解吗? p ...

  4. 简单的验证码识别(opecv)

    opencv版本: 3.0.0 处理验证码: 纯数字验证码 (颜色不同,有噪音,和带有较多的划痕) 测试时间 :  一天+一晚 效果: 比较挫,可能是由于测试的图片是在太小了的缘故. 原理:  验证码 ...

  5. 利用开源程序(ImageMagick+tesseract-ocr)实现图像验证码识别

    --------------------------------------------------低调的分割线-------------------------------------------- ...

  6. 基于LeNet网络的中文验证码识别

    基于LeNet网络的中文验证码识别 由于公司需要进行了中文验证码的图片识别开发,最近一段时间刚忙完上线,好不容易闲下来就继上篇<基于Windows10 x64+visual Studio2013 ...

  7. Java验证码识别解决方案

    建库,去重,切割,识别. package edu.fzu.ir.test; import java.awt.Color; import java.awt.image.BufferedImage; im ...

  8. 简单验证码识别(matlab)

    简单验证码识别(matlab) 验证码识别, matlab 昨天晚上一个朋友给我发了一些验证码的图片,希望能有一个自动识别的程序. 1474529971027.jpg 我看了看这些样本,发现都是很规则 ...

  9. Python验证码识别处理实例(转载)

    版权声明:本文为博主林炳文Evankaka原创文章,转载请注明出处http://blog.csdn.net/evankaka 一.准备工作与代码实例 1.PIL.pytesser.tesseract ...

随机推荐

  1. oracle 12C版本的下载安装

    首先 去官网下载自己需要的oracle对应的操作系统的版本 接受协议后可下载 1 下载解压好后 进入主目录  进行安装 在配置安全更新中把我希望通过My Oracle Support接收安全更新前面的 ...

  2. a标签与js的冲突

    如上图,需要做一个页面,点击左边的标题,右边就显示左边标题下的子标题的集合, html代码如下: <div id="newleft"> <ul> <l ...

  3. @GetMapping(value="/") , "/" 可加可不加 ,是不是一样的

    @GetMapping(value = "/user") 和  @GetMapping(value = "user") 的区别 1.带上 "/&quo ...

  4. 算法实践——舞蹈链(Dancing Links)算法求解数独

    在“跳跃的舞者,舞蹈链(Dancing Links)算法——求解精确覆盖问题”一文中介绍了舞蹈链(Dancing Links)算法求解精确覆盖问题. 本文介绍该算法的实际运用,利用舞蹈链(Dancin ...

  5. Hadoop — Yarn原理解析

    1. 概述 Yarn是一个资源调度平台,负责为运算程序提供服务器运算资源,相当于一个分布式的操作系统平台:而MapReduce等运算程序则相当运行于操作系统之上的应用程序. 2. YARN的重要概念 ...

  6. 转---redshift database ---学习

    摘自他人 前沿 根据最近一段时间对redshift的研究,发现一些特性比较适合我们当前的业务. 1 比如它的快速恢复能力,因为这一点,我们可以尽量在redshit里面存放一定生命周期的数据,对过期的数 ...

  7. Win10升级.NET Framework 3.5或2.0遇到错误0x800f081f怎么办

    为了让win10系统更好地运行游戏,很多玩家都会在电脑中安装.NET Framework 3.5或.NET Framework 2.0.不过,部分用户在更新升级.NET Framework 3.5和2 ...

  8. ajax的优缺点

    ajax(Asynchronous Javascript And XML) 异步的js和XML 以前更多的是使用XML的数据格式,现在数据格式更多的是json   ajax的优势:单页面应用(SPA) ...

  9. SQL Server进阶(五)子查询

    概述 子查询的概念: 当一个查询是另一个查询的条件时,称之为子查询.子查询可以嵌套在主查询中所有位置,包括SELECT.FROM.WHERE.GROUP BY.HAVING.ORDER BY. 外面的 ...

  10. 24.join算法/锁_1

    一. JOIN算法1.1. JOIN 语法 mysql> select * from t4; +---+------+ | a | b | +---+------+ | | 11 | | | 5 ...