
在做验证码识别之前,需要做数据准备,即验证码图片,作为后续模型训练与验证的训练数据集和测试数据集。验证码图片在制作时主要关注以上几个点,随机色彩、随机生成四个字符(数字、大小写字母)、干扰因素,其中干扰因素和字符出现位置需要在范围内随机出现。
以下将使用PIL以及random两个库来实现,因为也比较简单,就不做额外说明了。

import random
from PIL import Image, ImageDraw, ImageFont
'''
@description: 验证码图片底色
@return: {tuple} 随机red、green、blue数值
'''
def getRandomColor():
r = random.randint(0, 255)
g = random.randint(0, 255)
b = random.randint(0, 255)
return (r, g, b)
'''
@description: 生成随机字符
@return: {str} 随机字符,包含数字、大小写字母
'''
def getRandomChar():
num = str(random.randint(0, 9))
lower = chr(random.randint(97, 122)) # 小写字母a~z
upper = chr(random.randint(65, 90)) # 大写字母A~Z
return random.choice([num, lower, upper]) # 随机选择数字、大小写字母返回
'''
@description: 在图片上随机画线条
@param {PIL.ImageDraw} 图片画笔 {int} 图片宽度 {int} 图片高度
'''
def drawLine(draw, width, height):
for i in range(4):
# 循环次数决定线条数量
x1 = random.randint(0, width)
x2 = random.randint(0, width)
y1 = random.randint(0, height)
y2 = random.randint(0, height)
# 根据左边点画线段,随机颜色作为线段颜色
draw.line((x1, y1, x2, y2), fill=getRandomColor())
'''
@description: 在图片上随机画点
@param {PIL.ImageDraw} {int} 图片宽度 {int} 图片高度
'''
def drawPoint(draw, width, height):
for i in range(50):
x = random.randint(0, width)
y = random.randint(0, height)
draw.point((x, y), fill=getRandomColor())
'''
@description: 生成验证码图片
@param {int} 图片宽度 {int} 图片高度 {str} 保存图片名,不含后缀 {str} 图片保存路径
'''
def createImg(width, height, save_name='test', save_path=''):
bg_color = getRandomColor()
# 创建随机背景色图片
img = Image.new(mode="RGB", size=(width, height), color=bg_color)
# 获取图片画笔,用户描绘字符
draw = ImageDraw.Draw(img)
# 修改字体,可以替换成其他字体ttf文件,填写文件存放路径即可
font = ImageFont.truetype(font="arial.ttf", size=36)
for i in range(4):
# 随机生成4个字符和颜色
random_char = getRandomChar()
random_color = getRandomColor()
# 避免文字颜色和背景颜色重合
while random_color == bg_color:
random_color = getRandomColor()
# 根据坐标填充文字
draw.text((10 + 30 * i, 3), text=random_char, fill=random_color, font=font)
# 增加干扰线、点
drawLine(draw, width, height)
drawPoint(draw, width, height)
# 打开图片操作,并保存在指定文件夹
with open(save_path+'/'+save_name+'.png', 'wb') as f:
img.save(f, format='png')
if __name__ == "__main__":
createImg(160, 50, 'test')
网友评论