Max Jaderberg用于生成合成样本的脚本解析

来源:互联网 发布:德州扑克 人工智能 编辑:程序博客网 时间:2024/06/06 17:38

博主十分青睐于使用合成样本来训练模型,因为这种方法非常简单可依赖,而在text detection领域里,提到合成样本不得不说一下VGG组的工作,有关利用合成样本(Synthetic Data)来训练模型的文章大家可以去http://www.robots.ox.ac.uk/~vgg/research/text/下查找。其中一作Max Jaderberg把他们合成样本的工具公开在了https://bitbucket.org/jaderberg/text-renderer/downloads 上面

里面word_renderer.py就是用于生成合成样本的主要脚本。这个脚本写的非常长,但是阅读起来并没有太大的难度。这里主要介绍一下运行这个脚本需要安装什么样的依赖库以及这个脚本的原理。


安装

这个脚本是建立在pygam这个游戏引擎基础上的,大家下载pygame的时候一定要注意一点!——“一定不要在官网下源码安装,一定不要用apt-get install,一定要从bitbucket上下载,地址是

https://bitbucket.org/pygame/pygame

因为官网给的源码有库丢失的情况!坑了个爹!

pygame的依赖库有这么几个 freetype,以及sdl,sdl-image,sdl-ttf,sdl还有其他扩展库可以不用安装。

把pygame的几个依赖库安装好了就可以编译pygame了,一般大家自己安装的时候都会遇到找不到pygame.freetype的情况,原因就是官网给的坑爹的源码缺少freetype,大家可以去src文件夹去查看便知。


原理

挖个坑,之后写

---------------------------------------------------------------1229 分割线-----------------------------------------------------------------------------

OK,开始填坑

1. main函数中,generate_sample()是关键的函数,所以下面我们要详细讲这个函数

2. generate_sample()中有如下几步

2.1 生成一个随机的字符串display_text,用来规定绘制的文字内容,label为display_text的长度

2.2 声明fs (Font State)用来声明字体的大小,加粗程度,是否倾斜,是否有下划线等等属性

2.3 声明bg_surf (pygame.Surface类) 用来做画板,画板初始化为纯黑画板,也就是全0矩阵

2.4 下面是将display_text的每个字符按照从中间到两边的顺序依次绘制到bg_surf上面。

字符绘制的方法如下:首先声明rect用来记录绘制字符的bounding box大小,然后用render_to函数以及被绘制文字的bounding box rect变量把文字绘制到bg_surf上面,并顺带将单字的bounding box放到数组char_bbs

字符绘制过程中会假如各种扰动,诸如curve以及rotation对字符串进行扭曲旋转

2.5 绘制完文字,我们得到的bg_surf可以认为是一个白底黑字的图像。但是在这里我要狠狠的指明的是,其实bg_surf在声明的时候是RGBA通道,而经过2.4步的绘制之后,只有alpha通道是有非0值的,与绘制的文字对应,而RGB通道还是全0的

2.6 现在bg_surf还是一个pygame.Surface类,并不是数组类,利用get_ga_image函数把bg_surf转为bg_arr. 这里着重讲一下get_ga_image函数。里面的pixels_red(), pixels_alpha() 我不解释,我重点解释一下n.concatenate((r,a), axis=2).swapaxes(0,1).    concatenate((r,a), axis=2) 是将R通道与Alpha通道叠成两层,我们看到,R通道是放在前面的,而这个通道的值其实是全0的。swapaxes(0,1)的作用是将图像转置,因为现在的图像并不是我们所想的水平文本行,而是竖直的镜像文本行。

2.7 bg_arr[...,0] = cs['colours'][0] 意思是给前景的文字灰度赋值,而cs是colour_state类,是通过灰度值聚类得到的。随机选一个灰度中心给前景文字(后面会有操作把另一个灰度中心给背景)

2.8 'border' 关键字对应的是文字是否有阴影效果,这个效果是通过膨胀腐蚀得到的,阴影的部分也会有自己的cs值

2.9 下面就是做扰动了,affine与perspective

2.10 现在的文字是绘制在一个大的背景上的,我们只需要文字区域,所以需要把无用的背景给crop掉

2.11 canvas变量,这个变量是背景,灰度值取自cs

2.12 下面的操作是add_fillimage() 用来把前景l1_arr, 阴影l2_arr以及背景canvas与实际的背景图像分别融合。

2.13 剩下的就是把前景l1_arr, 阴影l2_arr以及背景canvas融合。然后做一些模糊扰动什么的。global_distortion() 函数里面有一个坑是,为了得到低分辨率的字,故意做了一次缩小放大的操作。所以如果你如果后期对图像做一些改动,比如说不做crop,获取含有大量背景的样本,这步缩小放大操作会让你得到根本认不出东西的样本。

3. 需要提及的一个坑是:这个代码给出的bounding box是极其不准的,大家需要针对固定字母固定大小写调整相应的bounding box,当然这个仅仅是我给出的处理方法,并不是完全之策,校正了还是会出一些单字bounding box不准的现象

好歹是把坑填了……

有兴趣的可以改一下代码,比如生成下面这样的样本→ →(请忽略水印)











2 0
原创粉丝点击