OCR技术3-大批量生成文字训练集

2024-03-03 18:48

本文主要是介绍OCR技术3-大批量生成文字训练集,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

如果是想训练一个手写体识别的模型,用一些前人收集好的手写文字集就好了,比如中科院的这些数据集。但是如果我们只是想要训练一个专门用于识别印刷汉字的模型,那么我们就需要各种印刷字体的训练集,那怎么获取呢?借助强大的图像库,自己生成就行了!

先捋一捋思路,生成文字集需要什么步骤:

  1. 确定你要生成多少字体,生成一个记录着汉字与label的对应表。
  2. 确定和收集需要用到的字体文件。
  3. 生成字体图像,存储在规定的目录下。
  4. 适当的数据增强。

第三步的生成字体图像最为重要,如果仅仅是生成很正规的文字,那么用这个正规文字集去训练模型,第一图像数目有点少,第二模型泛化能力比较差,所以我们需要对字体图像做大量的图像处理工作,以增大我们的印刷体文字数据集。

我总结了一下,我们可以做的一些图像增强工作有这些:

  1. 文字扭曲
  2. 背景噪声(椒盐)
  3. 文字位置(设置文字的中心点)
  4. 笔画粘连(膨胀来模拟)
  5. 笔画断裂(腐蚀来模拟)
  6. 文字倾斜(文字旋转)
  7. 多种字体

做完以上增强后,我们得到的数据集已经非常庞大了。

现在开始一步一步生成我们的3755个汉字的印刷体文字数据集。

一、生成汉字与label的对应表

这里的汉字、label映射表的生成我使用了pickel模块,借助它生成一个id:汉字的映射文件存储下来。
这里举个小例子说明怎么生成这个“汉字:id”映射表。

首先在一个txt文件里写入你想要的汉字,如果对汉字对应的ID没有要求的话,我们不妨使用该汉字的排位作为其ID,比如“一二三四五”中,五的ID就是00005。如此类推,把汉字读入内存,建立一个字典,把这个关系记录下来,再使用pickle.dump存入文件保存。

二、收集字体文件

字体文件上网收集就好了,但是值得注意的是,不是每一种字体都支持汉字,所以我们需要筛选出真正适合汉字生成的字体文件才可以。我一共使用了十三种汉字字体作为我们接下来汉字数据集用到的字体,具体如下图:

当然,如果需要进一步扩大数据集来增强训练得到的模型的泛化能力,可以花更多的时间去收集各类汉字字体,那么模型在面对各种字体时也能从容应对,给出准确的预测。

三、文字图像生成

首先是定义好输入参数,其中包括输出目录、字体目录、测试集大小、图像尺寸、图像旋转幅度等等。

def args_parse():#解析输入参数parser = argparse.ArgumentParser(description=description, formatter_class=RawTextHelpFormatter)parser.add_argument('--out_dir', dest='out_dir',default=None, required=True,help='write a caffe dir')parser.add_argument('--font_dir', dest='font_dir',default=None, required=True,help='font dir to to produce images')parser.add_argument('--test_ratio', dest='test_ratio',default=0.2, required=False,help='test dataset size')parser.add_argument('--width', dest='width',default=None, required=True,help='width')parser.add_argument('--height', dest='height',default=None, required=True,help='height')parser.add_argument('--no_crop', dest='no_crop',default=True, required=False,help='', action='store_true')parser.add_argument('--margin', dest='margin',default=0, required=False,help='', )parser.add_argument('--rotate', dest='rotate',default=0, required=False,help='max rotate degree 0-45')parser.add_argument('--rotate_step', dest='rotate_step',default=0, required=False,help='rotate step for the rotate angle')parser.add_argument('--need_aug', dest='need_aug',default=False, required=False,help='need data augmentation', action='store_true')   args = vars(parser.parse_args()) return args

接下来需要将我们第一步得到的对应表读入内存,因为这个表示ID到汉字的映射,我们在做一下转换,改成汉字到ID的映射,用于后面的字体生成。

#将汉字的label读入,得到(ID:汉字)的映射表label_dict
label_dict = get_label_dict()char_list=[]  # 汉字列表
value_list=[] # label列表
for (value,chars) in label_dict.items():print (value,chars)char_list.append(chars)value_list.append(value)# 合并成新的映射关系表:(汉字:ID)
lang_chars = dict(zip(char_list,value_list)) 
font_check = FontCheck(lang_chars) 

我们对旋转的角度存储到列表中,旋转角度的范围是[-rotate,rotate].

if rotate < 0:roate = - rotateif rotate > 0 and rotate <= 45:all_rotate_angles = []for i in range(0, rotate+1, rotate_step):  all_rotate_angles.append(i)for i in range(-rotate, 0, rotate_step):all_rotate_angles.append(i)#print(all_rotate_angles)

现在说一下字体图像是怎么生成的,首先我们使用的工具是PIL。PIL里面有很好用的汉字生成函数,我们用这个函数再结合我们提供的字体文件,就可以生成我们想要的数字化的汉字了。我们先设定好我们生成的字体颜色为黑底白色,字体尺寸由输入参数来动态设定。

# 生成字体图像
class Font2Image(object):def __init__(self,width, height,need_crop, margin):self.width = widthself.height = heightself.need_crop = need_cropself.margin = margindef do(self, font_path, char, rotate=0):find_image_bbox = FindImageBBox()# 黑色背景img = Image.new("RGB", (self.width, self.height), "black")draw = ImageDraw.Draw(img)font = ImageFont.truetype(font_path, int(self.width * 0.7),)# 白色字体draw.text((0, 0), char, (255, 255, 255),font=font)if rotate != 0:img = img.rotate(rotate)data = list(img.getdata())sum_val = 0for i_data in data:sum_val += sum(i_data)if sum_val > 2:np_img = np.asarray(data, dtype='uint8')np_img = np_img[:, 0]np_img = np_img.reshape((self.height, self.width))cropped_box = find_image_bbox.do(np_img)left, upper, right, lower = cropped_boxnp_img = np_img[upper: lower + 1, left: right + 1]if not self.need_crop:preprocess_resize_keep_ratio_fill_bg = \PreprocessResizeKeepRatioFillBG(self.width, self.height,fill_bg=False,margin=self.margin)np_img = preprocess_resize_keep_ratio_fill_bg.do(np_img)# cv2.imwrite(path_img, np_img)return np_imgelse:print("img doesn't exist.")

我们写两个循环,外层循环是汉字列表,内层循环是字体列表,对于每个汉字会得到一个image_list列表,里面存储着这个汉字的所有图像。

for (char, value) in lang_chars.items():  # 外层循环是字image_list = []print (char,value)#char_dir = os.path.join(images_dir, "%0.5d" % value)for j, verified_font_path in enumerate(verified_font_paths):    # 内层循环是字体   if rotate == 0:image = font2image.do(verified_font_path, char)image_list.append(image)else:for k in all_rotate_angles: image = font2image.do(verified_font_path, char, rotate=k)image_list.append(image)

我们将image_list中图像按照比例分为训练集和测试集存储。

   test_num = len(image_list) * test_ratiorandom.shuffle(image_list)  # 图像列表打乱count = 0for i in range(len(image_list)):img = image_list[i]#print(img.shape)if count < test_num :char_dir = os.path.join(test_images_dir, "%0.5d" % value)else:char_dir = os.path.join(train_images_dir, "%0.5d" % value)if not os.path.isdir(char_dir):os.makedirs(char_dir)path_image = os.path.join(char_dir,"%d.png" % count)cv2.imwrite(path_image,img)count += 1

写好代码后,我们执行如下指令,开始生成印刷体文字汉字集。

 python gen_printed_char.py --out_dir ./dataset --font_dir ./chinese_fonts --width 30 --height 30 --margin 4 --rotate 30 --rotate_step 1

解析一下上述指令的附属参数:

  1. --out_dir 表示生成的汉字图像的存储目录
  2. --font_dir 表示放置汉字字体文件的路径
  3. --width --height 表示生成图像的高度和宽度
  4. --margin 表示字体与边缘的间隔
  5. --rotate 表示字体旋转的范围,[-rotate,rotate]
  6. --rotate_step 表示每次旋转的间隔

生成这么一个3755个汉字的数据集的所需的时间还是很久的,估计接近一个小时。其实这个生成过程可以用多线程、多进程并行加速,但是考虑到这种文字数据集只需生成一次就好,所以就没做这方面的优化了。数据集生成完我们可以发现,在dataset文件夹下得到train和test两个文件夹,train和test文件夹下都有3755个子文件夹,分别存储着生成的3755个汉字对应的图像,每个子文件的名字就是该汉字对应的id。随便选择一个train文件夹下的一个子文件夹打开,可以看到所获得的汉字图像,一共634个。

dataset下自动生成测试集和训练集

测试集和训练集下都有3755个子文件夹,用于存储每个汉字的图像。

生成出来的汉字图像

 

 

额外的图像增强

第三步生成的汉字图像是最基本的数据集,它所做的图像处理仅有旋转这么一项,如果我们想在数据增强上再做多点东西,想必我们最终训练出来的OCR模型的性能会更加优秀。我们使用opencv来完成我们定制的汉字图像增强任务。

因为生成的图像比较小,仅仅是30*30,如果对这么小的图像加噪声或者形态学处理,得到的字体图像会很糟糕,所以我们在做数据增强时,把图片尺寸适当增加,比如设置为100×100,再进行相应的数据增强,效果会更好。

噪点增加

def add_noise(cls,img):for i in range(20): #添加点噪声temp_x = np.random.randint(0,img.shape[0])temp_y = np.random.randint(0,img.shape[1])img[temp_x][temp_y] = 255return img

适当腐蚀

def add_erode(cls,img):kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(3, 3))    img = cv2.erode(img,kernel) return img

适当膨胀

def add_dilate(cls,img):kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(3, 3))    img = cv2.dilate(img,kernel) return img

然后做随机扰动

def do(self,img_list=[]):aug_list= copy.deepcopy(img_list)for i in range(len(img_list)):im = img_list[i]if self.noise and random.random()<0.5:im = self.add_noise(im)if self.dilate and random.random()<0.25:im = self.add_dilate(im)if self.erode and random.random()<0.25:im = self.add_erode(im)    aug_list.append(im)return aug_list

输入指令

python gen_printed_char.py --out_dir ./dataset2 --font_dir ./chinese_fonts --width 100 --height 100 --margin 10 --rotate 30 --rotate_step 1 --need_aug

使用这种生成的图像如下图所示,第一数据集扩大了两倍,第二图像的丰富性进一步提高,效果还是明显的。当然,如果要获得最好的效果,还需要调一下里面的参数,这里就不再详细说明了。

 至此,我们所需的印刷体汉字数据集已经成功生成完毕,下一步要做的就是利用这些数据集设计一个卷积神经网络做文字识别了!

原文地址:http://www.cnblogs.com/skyfsm/p/8436820.html

 

欢迎扫码关注我的微信公众号

 

这篇关于OCR技术3-大批量生成文字训练集的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/770552

相关文章

MybatisGenerator文件生成不出对应文件的问题

《MybatisGenerator文件生成不出对应文件的问题》本文介绍了使用MybatisGenerator生成文件时遇到的问题及解决方法,主要步骤包括检查目标表是否存在、是否能连接到数据库、配置生成... 目录MyBATisGenerator 文件生成不出对应文件先在项目结构里引入“targetProje

Python使用qrcode库实现生成二维码的操作指南

《Python使用qrcode库实现生成二维码的操作指南》二维码是一种广泛使用的二维条码,因其高效的数据存储能力和易于扫描的特点,广泛应用于支付、身份验证、营销推广等领域,Pythonqrcode库是... 目录一、安装 python qrcode 库二、基本使用方法1. 生成简单二维码2. 生成带 Log

Python使用Pandas库将Excel数据叠加生成新DataFrame的操作指南

《Python使用Pandas库将Excel数据叠加生成新DataFrame的操作指南》在日常数据处理工作中,我们经常需要将不同Excel文档中的数据整合到一个新的DataFrame中,以便进行进一步... 目录一、准备工作二、读取Excel文件三、数据叠加四、处理重复数据(可选)五、保存新DataFram

SpringBoot生成和操作PDF的代码详解

《SpringBoot生成和操作PDF的代码详解》本文主要介绍了在SpringBoot项目下,通过代码和操作步骤,详细的介绍了如何操作PDF,希望可以帮助到准备通过JAVA操作PDF的你,项目框架用的... 目录本文简介PDF文件简介代码实现PDF操作基于PDF模板生成,并下载完全基于代码生成,并保存合并P

详解Java中如何使用JFreeChart生成甘特图

《详解Java中如何使用JFreeChart生成甘特图》甘特图是一种流行的项目管理工具,用于显示项目的进度和任务分配,在Java开发中,JFreeChart是一个强大的开源图表库,能够生成各种类型的图... 目录引言一、JFreeChart简介二、准备工作三、创建甘特图1. 定义数据集2. 创建甘特图3.

Redis KEYS查询大批量数据替代方案

《RedisKEYS查询大批量数据替代方案》在使用Redis时,KEYS命令虽然简单直接,但其全表扫描的特性在处理大规模数据时会导致性能问题,甚至可能阻塞Redis服务,本文将介绍SCAN命令、有序... 目录前言KEYS命令问题背景替代方案1.使用 SCAN 命令2. 使用有序集合(Sorted Set)

AI一键生成 PPT

AI一键生成 PPT 操作步骤 作为一名打工人,是不是经常需要制作各种PPT来分享我的生活和想法。但是,你们知道,有时候灵感来了,时间却不够用了!😩直到我发现了Kimi AI——一个能够自动生成PPT的神奇助手!🌟 什么是Kimi? 一款月之暗面科技有限公司开发的AI办公工具,帮助用户快速生成高质量的演示文稿。 无论你是职场人士、学生还是教师,Kimi都能够为你的办公文

【专题】2024飞行汽车技术全景报告合集PDF分享(附原数据表)

原文链接: https://tecdat.cn/?p=37628 6月16日,小鹏汇天旅航者X2在北京大兴国际机场临空经济区完成首飞,这也是小鹏汇天的产品在京津冀地区进行的首次飞行。小鹏汇天方面还表示,公司准备量产,并计划今年四季度开启预售小鹏汇天分体式飞行汽车,探索分体式飞行汽车城际通勤。阅读原文,获取专题报告合集全文,解锁文末271份飞行汽车相关行业研究报告。 据悉,业内人士对飞行汽车行业

高效录音转文字:2024年四大工具精选!

在快节奏的工作生活中,能够快速将录音转换成文字是一项非常实用的能力。特别是在需要记录会议纪要、讲座内容或者是采访素材的时候,一款优秀的在线录音转文字工具能派上大用场。以下推荐几个好用的录音转文字工具! 365在线转文字 直达链接:https://www.pdf365.cn/ 365在线转文字是一款提供在线录音转文字服务的工具,它以其高效、便捷的特点受到用户的青睐。用户无需下载安装任何软件,只

pdfmake生成pdf的使用

实际项目中有时会有根据填写的表单数据或者其他格式的数据,将数据自动填充到pdf文件中根据固定模板生成pdf文件的需求 文章目录 利用pdfmake生成pdf文件1.下载安装pdfmake第三方包2.封装生成pdf文件的共用配置3.生成pdf文件的文件模板内容4.调用方法生成pdf 利用pdfmake生成pdf文件 1.下载安装pdfmake第三方包 npm i pdfma