侯体宗的博客
  • 首页
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

Python3生成手写体数字方法

Python  /  管理员 发布于 7年前   261

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-9num = str(random.randint(1, 9))# 设置字体,这里选取字体大小25font = 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 ospath_folders = "F:/***/P_generate_handwritten_number/data_pngs/"# 1-9for 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 randomfrom PIL import Image, ImageDraw, ImageFilter, ImageFontrandom.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, numpath_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 = 200for 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 randomfrom PIL import Image, ImageDraw, ImageFilter, ImageFontrandom.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, charpath_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 ospath_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进度条实时显示处理进度的示例代码
    下一条:
    python字符串的方法与操作大全
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • 在python语言中Flask框架的学习及简单功能示例(0个评论)
    • 在Python语言中实现GUI全屏倒计时代码示例(0个评论)
    • Python + zipfile库实现zip文件解压自动化脚本示例(0个评论)
    • python爬虫BeautifulSoup快速抓取网站图片(1个评论)
    • vscode 配置 python3开发环境的方法(0个评论)
    • 近期文章
    • 在windows10中升级go版本至1.24后LiteIDE的Ctrl+左击无法跳转问题解决方案(0个评论)
    • 智能合约Solidity学习CryptoZombie第四课:僵尸作战系统(0个评论)
    • 智能合约Solidity学习CryptoZombie第三课:组建僵尸军队(高级Solidity理论)(0个评论)
    • 智能合约Solidity学习CryptoZombie第二课:让你的僵尸猎食(0个评论)
    • 智能合约Solidity学习CryptoZombie第一课:生成一只你的僵尸(0个评论)
    • 在go中实现一个常用的先进先出的缓存淘汰算法示例代码(0个评论)
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(95个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2016-10
    • 2016-11
    • 2018-04
    • 2020-03
    • 2020-04
    • 2020-05
    • 2020-06
    • 2022-01
    • 2023-07
    • 2023-10
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客