Python3⽣成⼿写体数字数据集
0.引⾔
平时经常会接触到验证码,或者在机器学习学习过程中,⼤家或许会接触过⼿写体识别/验证码识别之类问题,会⽤到⼿写体的数据集;
⾃⼰尝试写了⼀个⽣成⼿写体图⽚的 Python 程序,可以批量⽣成⼿写体数字数据集,在此分享下⽣成 30*30像素 的⼿写体数字1-9 图⽚ 的⼀种实现⽅法;
⼤概流程:新建空⽩图像 >>> ⽣成随机数 1-9 >>> 将数字写到空⽩图像上 >>> 旋转、扭曲 处理 >>> 得到 “⼿写体数字”;
得到的⼿写体数字图像如 图1 所⽰,实现⽐较简单,有兴趣可以⾃⼰试;
图1 ⽣成的⼿写体数字 1-9
图 2 利⽤ generate_imgs.py 得到数字 3 图像
1. 设计流程
图 4 整体设计流程
图 5 ⽣成的图像经过的处理
1.1 新建⼀个空⽩图像 img_50,尺⼨⼤⼩为 50*50
1 img_50_blank = w('RGB', (50, 50), (255, 255, 255))
想要的 30*30 的图像,为什么我这⾥要先⽣成 50*50 的空⽩图像?
因为图像背景(50*50像素的画布)初始化的时候设置为⽩⾊(颜⾊数组(255, 255, 255)),⽽背景⾊之外的其实是⿊⾊;
之后需要进⾏旋转处理,如果直接新建 30*30 像素的画布,旋转之后边上会出现⿊边,如 图6 所⽰;
所以我新建了⼀个 50*50,然后旋转之后从中间裁出来⼀个 30*30 的图像出来;
图 6 直接⽤ 30*30 像素的画布写字旋转(会出现⿊边)
1.2 利⽤ PIL 在图像上写⽂字 text
利⽤ PIL 的 ImageDraw,创建画笔,然后利⽤ 在指定位置写字;
xy=(18,11) 是从图像左上⾓开始的坐标,取值⾃⼰根据需求调整;
1# 创建画笔
2 draw = ImageDraw.Draw(img_50_blank)
3
4# ⽣成随机数1-9
5 num = str(random.randint(1, 9))
6
7# 设置字体,这⾥选取字体⼤⼩25
8 font = uetype('', 20)
9
10# xy是左上⾓开始的位置坐标
(xy=(18, 11), font=font, text=num, fill=(0, 0, 0))
1.3 将图像随机旋转⼀定⾓度
利⽤ rotate(angel) 进⾏旋转图像,angel 取的是度数,这⾥让它随机旋转 -10 到 +10 度:
1# 随机旋转-10-10⾓度
2 random_angle = random.randint(-10, 10)
3 img_50_rotated = img_ate(random_angle)
1.4 图像扭曲
这⾥是⽣成“⼿写体”数字的 核⼼ 步骤,⼀个正常的图像经过扭曲之后就可以得到想要的验证码了:
1# 图形扭曲参数
2 params = [1 - float(random.randint(1, 2)) / 100,
3 0,
4 0,
5 0,
6 1 - float(random.randint(1, 10)) / 100,
7 float(random.randint(1, 2)) / 500,
8 0.001,
9 float(random.randint(1, 2)) / 500]
apache log4j2 远程代码执行漏洞10
枇杷果图片11# 创建扭曲
12 img_50_transformed = img_ansform((50, 50), Image.PERSPECTIVE, params)
2. Source Code 介绍
2.1 函数 mkdir_for_imgs()
因为我们要将指定的图像分类放⼊指定⽂件夹,所以我们需要先在项⽬⽬录下⾯新建 9 个⽂件夹:
(当然你也可以⾃⼰新建,新建 9 个⽂件夹⼯作量还不⼤,但是如果要⽣成的验证码包含英⽂字母那就⽐较多了,⼤写 A-Z 共 24 个 +⼩写 a-z 共 24 个 + 数字 1-9 共 9 个 = 57个⼦⽂件夹)soap全科病历书写范文
1# 在⽬录下⽣成⽤来存放数字 1-9 的 9个⽂件夹,分别⽤ 1-9 命名
2def mkdir_for_imgs():
3for i in range(49, 58):
4if os.path.isdir(path_img + "Num_" + chr(i)):
5pass
6else:
7print(path_img + "Num_" + chr(i))
8 os.mkdir(path_img + "Num_" + chr(i))
图 7 mkdir_for_imgs() ⽣成的⽤来存放指定图像的⽂件夹
2.2 函数 del_imgs()
删除⼦⽂件夹 Num_1-9 中的所有图⽚:
1# 删除路径下的图⽚
2def del_imgs():
3for i in range(1, 10):
4 dir_nums = os.listdir(path_img+ "Num_" + str(i))
5for tmp_img in dir_nums:
6if tmp_img in dir_nums:
7# print("delete: ", tmp_img)
8 os.remove(path_img + "Num_" + str(i) + "/" + tmp_img)
9print("Delete finish", "\n")
2.3 完整的代码 generate_imgs.py
mkdir_for_imgs() >>> del_imgs() >>> generate_1to9(n)
根据给定随机次数⽣成⼿写体数字 1-9,然后存放到本地⽂件夹 Num_1-9 ;
Line 67 修改⽣成图像的⼤⼩,我这⾥取的是 30*30 像素;
79 # ⽣成新的30*30空⽩图像
80 im_30 = im_p([10, 10, 40, 40])
Line 105 给定⽣成⼿写体数字的次数:
116 # generate n times
117 generate_1to9(1000)
generate_imgs.py:
1# Created on: 2018-01-09
2# Updated on: 2018-09-03
3# Author: coneypo
4# Blog: wwwblogs/AdaminXie/
5# Github: github/coneypo/Generate_handwritten_number
6# ⽣成⼿写体数字
7
8
9import random
10import os
11from PIL import Image, ImageDraw, ImageFont
11from PIL import Image, ImageDraw, ImageFont
python基础代码写字12
13 random.seed(3)
14 path_img = "data_pngs/"
15
16
17# 在⽬录下⽣成⽤来存放数字 1-9 的 9个⽂件夹,分别⽤ 1-9 命名 18def mkdir_for_imgs():
19for i in range(49, 58):
graduate快速记忆20if os.path.isdir(path_img + "Num_" + chr(i)):
21pass
22else:
23print(path_img + "Num_" + chr(i))
c程序设计第五版期末考试24 os.mkdir(path_img + "Num_" + chr(i))
25
26
27# generate folders
28# mkdir_for_imgs()
29
30
31# 删除路径下的图⽚
32def del_imgs():
33for i in range(1, 10):
34 dir_nums = os.listdir(path_img+ "Num_" + str(i))
35for tmp_img in dir_nums:
36if tmp_img in dir_nums:
37# print("delete: ", tmp_img)
38 os.remove(path_img + "Num_" + str(i) + "/" + tmp_img) 39print("Delete finish", "\n")
40
41
42 del_imgs()
43
44
45# ⽣成单张扭曲的数字图像
46def generate_single():
47# 先绘制⼀个50*50的空图像
48 im_50_blank = w('RGB', (50, 50), (255, 255, 255)) 49
50# 创建画笔
51 draw = ImageDraw.Draw(im_50_blank)
52
53# ⽣成随机数1-9
54 num = str(random.randint(1, 9))
55
56# 设置字体,这⾥选取字体⼤⼩25
57 font = uetype('', 20)
58
59# xy是左上⾓开始的位置坐标
60 (xy=(18, 11), font=font, text=num, fill=(0, 0, 0))
61
62# 随机旋转-10-10⾓度
63 random_angle = random.randint(-10, 10)
64 im_50_rotated = im_ate(random_angle)
65
66# 图形扭曲参数
67 params = [1 - float(random.randint(1, 2)) / 100,
68 0,
69 0,
70 0,
71 1 - float(random.randint(1, 10)) / 100,
72 float(random.randint(1, 2)) / 500,
73 0.001,
74 float(random.randint(1, 2)) / 500]
75
76# 创建扭曲
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论