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

本文标题: Python3生成手写体数字方法

本文地址: http://www.cppcns.com/jiaoben/python/219053.html

python数字1 3怎么表示_Python3生成手写体数字方法相关推荐

  1. python写数字,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数字1 3怎么表示_Python3数据类型之数字

    1. Python数字类型的作用 Python数字类型用来存储数值,它是不可变对象,一旦定义之后,其值不可以被修改.如果改变了数字类型的值,就要重新为其分配内存空间. 定义一个数字类型的变量:a = ...

  7. 使用python进行数据清洗常用的库_python3常用的数据清洗方法(小结)

    首先载入各种包: import pandas as pd import numpy as np from collections import Counter from sklearn import ...

  8. 基于Keras的生成对抗网络(1)——利用Keras搭建简单GAN生成手写体数字

    目录 0.前言 一.GAN结构 二.函数代码 2.1 生成器Generator 2.2 判别器Discriminator 2.3 train函数 三.结果演示 四.完整代码 五.常见问题汇总 0.前言 ...

  9. Python 3 利用机器学习模型 进行手写体数字检测

    0.引言 介绍了如何生成手写体数字的数据,提取特征,借助 sklearn 机器学习模型建模,进行识别手写体数字 1-9 模型的建立和测试. 用到的几种模型: 1. LR,Logistic Regres ...

最新文章

  1. 独家 | 快速掌握spacy在python中进行自然语言处理(附代码链接)
  2. IOS开发笔记7-C语言基础复习
  3. CSS样式让一个块在最上层中显示
  4. 街霸2的CPU是怎么对玩家作弊的?
  5. 一些比较有用的SQL操作,2011最新整理
  6. 静态类 c# 1615139615
  7. django-orm查询-验证是否存在的方式
  8. Html学习总结(2)——Html页面head标签元素的意义和应用场景
  9. Mutes锁_递归锁_信号量semaphore
  10. 一次性掌握计算机中常见的六类指令
  11. 《学术小白的学习之路 02》情感分析02 之基于大连理工情感词典的情感分析和情绪计算
  12. 有一种生活叫向死而生
  13. 开关插头插座寿命试验机标准
  14. 计算机usb无法读取u盘启动,U盘无法识别的USB设备怎么办解决
  15. 论文阅读:Meta-Learning in Neural Networks: A Survey
  16. string类型--字符串常用取值操作
  17. 英语学习思路【罗肖尼Shawney】
  18. 7个靠谱的Windows软件下载网站,个个「纯净、安全、无捆绑」!
  19. $.messager的使用笔记
  20. 3D打印与传统制造的优势

热门文章

  1. mysql校验日期是否有效_Mysql 根据出生日期计算年龄 判断起始日期是否在某个有效时间段内等日期Hack汇总...
  2. python3 copy和deepcopy
  3. 影响平面设计师的必然因素——节奏感
  4. 设计图形抽象类java_Java基础——抽象类
  5. 通过BPE解决OOV问题----Neural machine Translation of Rare Words with Subword Units
  6. gensim-fast2vec改造、灵活使用大规模外部词向量(具备OOV查询能力)
  7. vue项目--资产管理系统
  8. 华为IdeaHub的商业市场启示“路”
  9. Redis 服务配置 redis.conf 配置文件详解
  10. 机器学习----线性回归