0.引言

平时上网干啥的基本上都会接触验证码,或者在机器学习学习过程中,大家或许会接触过手写体识别/验证码识别之类问题,会用到手写体的数据集;

自己尝试写了一个生成手写体图片的python程序,在此分享下生成单张 30*30像素的手写体数字1-9图像 的一种实现方法;

我是利用random生成随机数1-9,然后PIL写到图像上,然后经过旋转、扭曲处理,得到“手写体”,这里没有加干扰线和干扰点;

得到的手写体数字图像如图1所示;

实现比较简单,用了PIL库,不需要额外安装opencv啥的,有兴趣可以自己试试。

图1 生成的手写体数字1-9

图2 利用generate_pngs.py写入到文件夹3的数字3图像

如果你想生成手写体的字母/汉字也可以:

图3 利用generate_single_png.py生成汉字的手写体

源码上传到了我的GitHub: https://github.com/coneypo/Generate_handwritten_number

1.设计流程

图4 整体设计流程

图5 生成的图像经过的处理

1.1 新建一个空白图像img_50,尺寸大小为50*50

img_50_blank = Image.new('RGB', (50, 50), (255, 255, 255))

为什么我这里要先生成50*50的空白图像?

因为图像背景(50*50像素的画布)初始化的时候设置为白色(颜色数组(255, 255, 255)),而背景色之外的其实是黑色;

之后需要进行旋转处理,如果直接新建30*30像素的画布,旋转之后边上会出现黑边,如图6所示;

所以我新建了一个50*50,然后旋转之后从中间裁出来一个30*30的图像出来;

图6 直接用30*30像素的画布写字旋转(会出现黑边)

1.2 利用PIL在图像上写文字

利用PIL的ImageDraw,创建画笔,然后利用draw.text在指定位置写字;

xy=(18,11)是从图像左上角开始的坐标,取值自己根据需求调整;

# 创建画笔

draw = ImageDraw.Draw(img_50_blank)

# 生成随机数1-9

num = str(random.randint(1, 9))

# 设置字体,这里选取字体大小25

font = ImageFont.truetype('simsun.ttc', 20)

# xy是左上角开始的位置坐标

draw.text(xy=(18, 11), font=font, text=num, fill=(0, 0, 0))

1.3 将图像随机旋转一定角度

利用 rotate(angel) 进行旋转图像,angel取的是度数,这里让它随机旋转-10到+10度:

# 随机旋转-10-10角度

random_angle = random.randint(-10, 10)

img_50_rotated = img_50_blank.rotate(random_angle)

1.4 图像扭曲

这里是生成“手写体”数字的核心步骤,一个正常的图像经过扭曲之后就可以得到想要的验证码了:

# 图形扭曲参数

params = [1 - float(random.randint(1, 2)) / 100,

0,

0,

0,

1 - float(random.randint(1, 10)) / 100,

float(random.randint(1, 2)) / 500,

0.001,

float(random.randint(1, 2)) / 500]

# 创建扭曲

img_50_transformed = img_50_rotated.transform((50, 50), Image.PERSPECTIVE, params)

2.py源码介绍

2.1 generate_folders_1to9.py

因为我们要将指定的图像分类放入指定文件夹,所以我们需要先在项目目录下面新建9个文件夹:

(当然你也可以自己新建,新建9个文件夹工作量还不大,但是如果要生成的验证码包含英文字母那就比较多了,大写A-Z共24个+小写a-z共24个+数字1-9共9个=57个子文件夹)

# 2018-01-9

# By TimeStamp

# cnblogs: http://www.cnblogs.com/AdaminXie/

# generate_folders_1to9.py

# 在目录下生成用来存放数字1-9的9个文件夹,分别用1-9命名

import os

path_folders = "F:/***/P_generate_handwritten_number/data_pngs/"

# 1-9

for i in range(49,58):

if (os.path.isdir(path_folders + chr(i))):

pass

else:

# print(i,": ",path_1+chr(i))

# 生成目录

os.mkdir(path_folders+chr(i))

图7 自动生成的用来存放指定图像的文件夹

2.2 generate_pngs.py

根据给定随机次数samples, 生成samples个手写体数字1-9,然后存放到本地文件夹1-9生成数据集;

在49行可以修改生成图像的大小,我这里取的是30*30像素;

# 2018-01-9

# By TimeStamp

# cnblogs: http://www.cnblogs.com/AdaminXie/

# generate_pngs.py

# 生成手写体数字

import random

from PIL import Image, ImageDraw, ImageFilter, ImageFont

random.seed(3)

# 生成单张扭曲的数字图像

def generate_single():

# 先绘制一个50*50的空图像

img_50_blank = Image.new('RGB', (50, 50), (255, 255, 255))

# 创建画笔

draw = ImageDraw.Draw(img_50_blank)

# 生成随机数1-9

num = str(random.randint(1, 9))

# 设置字体,这里选取字体大小25

font = ImageFont.truetype('simsun.ttc', 20)

# xy是左上角开始的位置坐标

draw.text(xy=(18, 11), font=font, text=num, fill=(0, 0, 0))

# 随机旋转-10-10角度

random_angle = random.randint(-10, 10)

img_50_rotated = img_50_blank.rotate(random_angle)

# 图形扭曲参数

params = [1 - float(random.randint(1, 2)) / 100,

0,

0,

0,

1 - float(random.randint(1, 10)) / 100,

float(random.randint(1, 2)) / 500,

0.001,

float(random.randint(1, 2)) / 500]

# 创建扭曲

img_50_transformed = img_50_rotated.transform((50, 50), Image.PERSPECTIVE, params)

# 生成新的30*30空白图像,(在此处可以更改生成的图像大小)

img_30 = img_50_transformed.crop([10, 10, 40, 40])

return img_30, num

path_pic = "F:/***/P_generate_handwritten_number/data_pngs/"

# 生成手写体数字1-9存入指定文件夹1-9

# 用cnt_num[1]-cnt_num[9]来计数数字1-9生成的个数,方便之后进行命名

cnt_num = []

for i in range(10):

cnt_num.append(0)

# 生成次数

samples = 200

for m in range(1, samples+1):

# 调用生成图像文件函数

img, generate_num = generate_single()

# 取灰度

imgray = img.convert('1')

# 计数生成的数字1-9的个数,用来命名图像文件

for j in range(1, 10):

if(generate_num == str(j)):

cnt_num[j] = cnt_num[j]+1

# 路径如 "F:/code/***/P_generate_handwritten_number/data_pngs/1/1_231.png"

# 输出显示路径

print(path_pic + str(j) + "/" + str(j) + "_" + str(cnt_num[j]) + ".png")

# 将图像保存在指定文件夹中

imgray.save(path_pic + str(j) + "/" + str(j) + "_" + str(cnt_num[j]) + ".png")

# 输出显示1-9的分布

print("\n", "生成的1-9的分布:")

for k in range(9):

print(k+1, ":", cnt_num[k+1], "张")

output

D:\***\anaconda\python.exe F:/***/P_generate_handwritten_number/generate_pngs.py

F:/***/P_generate_handwritten_number/data_pngs/4/4_1.png

F:/***/P_generate_handwritten_number/data_pngs/1/1_1.png

F:/***/P_generate_handwritten_number/data_pngs/8/8_1.png

F:/***/P_generate_handwritten_number/data_pngs/3/3_1.png

F:/***/P_generate_handwritten_number/data_pngs/1/1_2.png

...

生成的1-9的分布:

: 25 张

: 17 张

: 21 张

: 19 张

: 20 张

: 22 张

: 25 张

: 24 张

: 27 张

修改 generate_pngs.py中的samples, 你就可以生成指定大小的数据集;

2.3 generate_single_png.py

更改27行的char=" "(可以是数字/字母/汉字),生成单张手写体扭曲图像:

# 2018-01-9

# By TimeStamp

# cnblogs: http://www.cnblogs.com/AdaminXie/

# generate_single_png.py

# 生成手写体数字/字母/汉字

import random

from PIL import Image, ImageDraw, ImageFilter, ImageFont

random.seed(3)

# 生成单张扭曲的数字图像

def generate_single():

# 先绘制一个50*50的空图像

img_50_blank = Image.new('RGB', (50, 50), (255, 255, 255))

# 创建画笔

draw = ImageDraw.Draw(img_50_blank)

# 设置字体,这里选取字体大小25

font = ImageFont.truetype('simsun.ttc', 20)

# xy是左上角开始的位置坐标

# text是你想要显示的内容,数字/字母/汉字

char ="呵"

draw.text(xy=(12, 11), font=font, text=char, fill=(0, 0, 0))

# 随机旋转-10-10角度

random_angle = random.randint(-10, 10)

img_50_rotated = img_50_blank.rotate(random_angle)

# 图形扭曲参数

params = [1 - float(random.randint(1, 2)) / 100,

0,

0,

0,

1 - float(random.randint(1, 10)) / 100,

float(random.randint(1, 2)) / 500,

0.001,

float(random.randint(1, 2)) / 500]

# 创建扭曲

img_50_transformed = img_50_rotated.transform((50, 50), Image.PERSPECTIVE, params)

# 生成新的30*30空白图像

img_30 = img_50_transformed.crop([10, 10, 40, 40])

return img_30, char

path_pic = "F:/code/python/P_generate_handwritten_number/"

# 调用生成图像文件函数

img, generated_char = generate_single()

imgray = img.convert('1')

print(path_pic + "test.png")

# 将图像保存在指定文件夹中

imgray.save(path_pic + "test.png")

2.4 del_pngs.py

删除指定目录下子文件夹1-9中的所有图片:

# 2018-01-9

# By TimeStamp

# cnblogs: http://www.cnblogs.com/AdaminXie/

# del_pngs.py

# 删除路径下生成的图像文件

import os

path_pic = "F:/***/P_generate_handwritten_number/data_pngs/"

#删除路径下的图片

def del_pic():

for i in range(1, 10):

# print(path_png+chr(i))

namedir = os.listdir(path_pic+str(i))

for tmppng in namedir:

if( tmppng in namedir):

# print(tmppng)

os.remove(path_pic+str(i)+"/"+tmppng)

del_pic()

3.总结

自己动手丰衣足食,有兴趣可以自己做手写体数字数据集,字母和汉字的数据集稍加修改也可以做;

# GitHub: https://github.com/coneypo/Generate_handwritten_number

python写数字,Python3生成手写体数字方法相关推荐

  1. python数字1 3怎么表示_Python3生成手写体数字方法

    0.引言 平时上网干啥的基本上都会接触验证码,或者在机器学习学习过程中,大家或许会接触过手写体识别/验证码识别之类问题,会用到手写体的数据集: 自己尝试写了一个生成手写体图片的python程序,在此分 ...

  2. python制作图片数据集,Python 3 生成手写体数字数据集

    0.引言 平时上网干啥的基本上都会接触验证码,或者在机器学习学习过程中,大家或许会接触过手写体识别/验证码识别之类问题,会用到手写体的数据集: 自己尝试写了一个生成手写体图片的python程序,在此分 ...

  3. GAN网络生成手写体数字图片

    Keras真香,以前都是用tensorflow来写神经网络,自从用了keras,发现这个Keras也蛮方便的. 目前感觉keras的优点就是方便搭建基于标准网络组件的神经网络,这里的网络组件包括全连接 ...

  4. 图像对抗生成网络 GAN学习01:从头搭建最简单的GAN网络,利用神经网络生成手写体数字数据(tensorflow)

    图像对抗生成网络 GAN学习01:从头搭建最简单的GAN网络,利用神经网络生成手写体数字数据(tensorflow) 文章目录 图像对抗生成网络 GAN学习01:从头搭建最简单的GAN网络,利用神经网 ...

  5. tensorflow学习笔记(十):GAN生成手写体数字(MNIST)

    文章目录 一.GAN原理 二.项目实战 2.1 项目背景 2.2 网络描述 2.3 项目实战 一.GAN原理 生成对抗网络简称GAN,是由两个网络组成的,一个生成器网络和一个判别器网络.这两个网络可以 ...

  6. 使用Python预处理机器学习需要的手写体数字图像文件数据集

    封面图片:<Python程序设计实验指导书>,董付国,清华大学出版社 ============= 问题描述:为演示机器学习算法对手写体数字识别与分类,需要准备大量数据,如果自己写的话需要很 ...

  7. python字典生成器,生成纯数字字典、英文字典、混合字典。

    import itertoolsdef save(address,listtotal):with open(address,'w') as f:i=len(listtotal)n=0for conte ...

  8. mysql中随机16位数字_MySQL 生成随机数字、字符串、日期、验证码及 UUID的方法

    上一篇介绍了如何在 Oracle 生成随机数字.字符串.日期.验证码以及 UUID,今天我们继续讨论在 MySQL 中生成各种随机数据的方法.

  9. python字母表_Python 一句话生成字母表的方法

    Python 一句话生成字母表的方法 List >>> [chr(i) for i in range(97,123)] ['a', 'b', 'c', 'd', 'e', 'f', ...

最新文章

  1. 【C#】Out与ref是干什么的?
  2. Python生产环境部署(fastcgi,uwsgi)
  3. XamarinEssentials教程首选项Preferences判断项目是否存在
  4. TCP:SEQ号与ACK号
  5. 【Python】青少年蓝桥杯_每日一题_12.03_输出字符串的长度
  6. 处理时间_5_计算时间列所在年的周序号
  7. mysql函数及解析,Mysql研究之MySQL常用内置函数完全解析
  8. 剑指Offer - 面试题51. 数组中的逆序对(归并排序,求逆序对)
  9. 朱晔的互联网架构实践心得S2E3:品味Kubernetes的设计理念
  10. 汽车域控制器(上):动力域控制器、底盘域控制器、智能座舱域控制器
  11. Centos网络管理(三)-网络配置相关
  12. 关于计算机高中英语作文,关于电脑的高中英语作文:Computers
  13. 用BeautifulSoup爬取豆瓣的电影排行榜,并用xlwt把数据保存成excel
  14. 人工智能真的要取代人类了?
  15. 哥本哈根大学计算机科学,2020年哥本哈根大学有哪些优势专业
  16. iVMS-4200 Vs区别_【5G科普】5G知识知多少?#之5G与4G的区别
  17. 二向箔-百日打卡writeup16-20
  18. java 笔试题一套_软世通分享一套Java笔试题
  19. codecombat极客战记--山峰--士兵的祸害
  20. PostwomanApi接口测试工具

热门文章

  1. DCDC电源测试以及纹波测试方法
  2. 监理工程师岁月--甲乙丙方的斗智斗勇
  3. 菜鸟初次安装CP2K笔记
  4. iBatis详解以及和MyBatis区别
  5. 第二讲:网线的制作方法及步骤
  6. 教师在初中数学课堂该如何有效提问(内有示例)
  7. 【小河今学 | JavaScript + JQuery】音乐播放器4-音量调整、单曲循环、全部循环
  8. 访问FTP 报错:打开FTP服务器上的文件夹时发生错误。请检查是否有权限访问该文件夹 550 No such file or directory
  9. 数据增广真有那么神奇吗?
  10. Jquery手册中常用的方法