文本检测之CTPN

论文作者现在就坐在旁边位置, 过来拜读一下他以前的文章

之一:

简介

文章基本信息

论文题目:Detecting Text in Natural Image with Connectionist Text Proposal Network,简称CTPN.该文章是ECCV2016乔宇老师的文章

论文地址:https://arxiv.org/pdf/1609.03605.pdf

代码实现:https://github.com/tianzhi0549/CTPN(作者的caffe实现),https://github.com/eragonruan/text-detection-ctpn(其他人tensorflow实现)

作者提供的caffe实现没有训练代码,不过训练代码可以参考faster-rcnn的训练代码

文本检测概述

文本检测可以看成特殊的目标检测,但它有别于通用目标检测.在通用目标检测中,每个目标都有定义好的边界框,检测出的bbox与当前目标的groundtruth重叠率大于0.5就表示该检测结果正确.文本检测中正确检出需要覆盖整个文本长度,且评判的标准不同于通用目标检测,具体的评判方法参见(ICDAR 2017 RobustReading Competition).所以通用的目标检测方法并不适用文本检测

 

论文关键idea

  1. 采用垂直anchor回归机制,检测小尺度的文本候选框
  2. 文本检测的难点在于文本的长度是不固定,可以是很长的文本,也可以是很短的文本.如果采用通用目标检测的方法,将会面临一个问题:**如何生成好的text proposal**.针对上述问题,作者提出了一个vertical anchor的方法,具体的做法是只预测文本的竖直方向上的位置,水平方向的位置不预测。与faster rcnn中的anchor类似,但是不同的是,vertical anchor的宽度都是固定好的了,论文中的大小是16个像素。而高度则从11像素到273像素(每次除以0.7)变化,总共10个anchor.
  3. 采用RNN循环网络将检测的小尺度文本进行连接,得到文本行.
  4. 采用CNN+RNN端到端的训练方式,支持多尺度和多语言,避免后处理.

文本检测之CTPN_第1张图片

整体实现流程

CTPN的具体实现流程包含三个部分:**检测小尺度文本框**,**循环连接文本框**,**文本行边细化**.具体的实现步骤如下:

  1. 使用VGG16作为base net提取特征,得到conv5_3的特征作为feature map,大小是W×H×C
  2. 在上述的feature map上使用大小为$3\times3$的滑动窗进行滑动,每个窗口都能得到一个长度为3×3×C的特征向量,每个滑动窗口中心都会预测k个相对于anchor的偏移
  3. 将上一步得到的特征输入到一个双向的LSTM中,得到长度为W×256的输出,然后接一个512的全连接层,准备输出。
  4. 输出层部分主要有三个输出。2k个vertical coordinate,因为一个anchor用的是中心位置的高(y坐标)和矩形框的高度两个值表示的,所以一个用2k个输出。(注意这里输出的是相对anchor的偏移)。2k个score,因为预测了k个text proposal,所以有2k个分数,text和non-text各有一个分数。k个side-refinement,这部分主要是用来精修文本行的两个端点的,表示的是每个proposal的水平平移量。
  5. 使用一个标准的非极大值抑制算法来滤除多余的text proposal。
  6. 最后使用基于图的文本行构造算法,将得到的一个一个的文本段合并成文本行。

文本检测之CTPN_第2张图片

 

具体实现细节

垂直anchor

  • k个anchor的设置:宽度固定为16,高度范围为11~273像素(每次除以0.7)
  • 预测k个垂直坐标:

文本检测之CTPN_第3张图片

双向LSTM

  • 本文使用了双向的lstm,每个lstm有128个隐藏层
  • lstm可以利用文本序列的上下文信息,使得检测的文本行更加精确,尽可能减少误检(如窗户,砖块,叶子等造成的误检)

文本检测之CTPN_第4张图片

 

文本行的构造和细化

所有的text proposals只保留score大于0.7的proposal

  • 文本行构造规则

判断text proposals是否属于同一个文本行的定义规则如下:

Bj到Bi的距离最近(水平距离)
Bj与Bi之间的距离小于50个pixel
垂直方向重叠大于0.7
Bj->Bi,同时Bi->Bj
  • 文本行的side-refinement

由于text proposal的宽度是固定16,这可能造成定位不准,部分text proposal被丢弃等

预测文本行的left和right的水平坐标
该处理过程融合在模型内,而非后处理

训练

训练labels

  • 正样本
与真值IoU大于0.7的anchor作为正样本,
与真值IoU最大的那个anchor也定义为正样本

这个时候不考虑IoU大小有没有到0.7,这样做有助于检测出小文本,这是有别于通用目标检测的关键点

  • 负样本
与真值IoU小于0.5的anchor定义为负样本

训练loss

模型的损失函数包含3部分:文本/非文本loss[采用的是softmax],垂直坐标loss[采用的是L1回归],side-refinement loss[采用的是L1回归],具体公式如下:

这里$\lambda_{1}=1,\lambda_{2}=2$,

 

训练参数

  • 对于每一张训练图片,总共抽取128个样本,64正64负,如果正样本不够就用负样本补齐。这个和faster rcnn的做法是一样的。
  • 训练图片都将短边放缩到600像素,并且保持原图的缩放比
  • RNN层和output层采用随机均值为0,方差为1的参数进行初始化
  • 在训练时CNN的前两层参数固定

 

测试集上的评估结果

文本检测之CTPN_第5张图片

 

 

利用CTPN训练自己的数据

这里采用的代码是https://github.com/eragonruan/text-detection-ctpn

编译源码

cd lib/utils
chmod +x Make.sh | Design and Development
./make.sh

准备数据

  • 数据标注

这里我在标注数据的时候采用的是顺时针方向,一次是左上角坐标点,右上角坐标点,右下角坐标点,左下角坐标点(即x1,y1,x2,y2,x3,y3,x4,y4),,这里的标注方式与通用目标检测的目标检测方式一样,这里我标注的数据是生成到txt中,具体格式如下:

文本检测之CTPN_第6张图片

  • 数据处理

根据ctpn训练数据的要求,需要对上述数据(txt标注数据)进一步处理,生成对应的xml文件,具体格式参见pascal voc.具体的训练数据截图和生成的pascal voc格式如下图:

文本检测之CTPN_第7张图片

文本检测之CTPN_第8张图片

处理数据的时候可以执行:

cd lib/prepare_training_data
python split_label.py
python ToVoc.py
cd ../../data
ln -s TEXTVOC VOCdevkit2007

注意:这里生成的数据会在当前目录下,文件夹为TEXTVOC,需要将该文件夹移至/data目录下,然后在做VOCdevikt2007的软连接文本检测之CTPN

 

 

训练

这里你可以指定在哪块显卡上运行,我这里选择在第一块显卡上训练,训练中间过程图在这里就不放了,具体的训练命令如下:

CUDA_VISIBLE_DEVICES="0" python ./ctpn/train_net.py

部分检测结果

以下展示了部分检测结果,可以发现ctpn在检测水平文字效果确实不错,但是在垂直方向和倾斜方向效果相对较差:

文本检测之CTPN_第9张图片

文本检测之CTPN_第10张图片

文本检测之CTPN_第11张图片

文本检测之CTPN_第12张图片

 

 

 

总结及存在的困惑

总结

  • ctpn在检测在水平方向的文字效果比较好,但是在其它方向的检测效果相对较差

困惑

  • side-refinement的输出为什么是k个?它是bbox最左边和最右边相对ground truth的偏移

 

之二:

简介

本文将对CTPN这篇文章的思路做一个详细的介绍,同时对代码进行解读。
论文地址:arxiv
作者github地址:github
tensorflow版本地址:tensorflow
作者提供的版本使用的caffe,没有提供训练的代码,但是有一个online的demo


论文的关键idea

  • 文本检测的其中一个难点就在于文本行的长度变化是非常剧烈的。因此如果是采用基于faster rcnn等通用物体检测框架的算法都会面临一个问题?怎么生成好的text proposal?这个问题实际上是比较难解决的。因此在这篇文章中作者提供了另外一个思路,检测一个一个小的,固定宽度的文本段,然后再后处理部分再将这些小的文本段连接起来,得到文本行。检测到的文本段的示意图如下图所示。
  • 具体的说,作者的基本想法就是去预测文本的竖直方向上的位置,水平方向的位置不预测。因此作者提出了一个vertical anchor的方法。与faster rcnn中的anchor类似,但是不同的是,vertical anchor的宽度都是固定好的了,论文中的大小是16个像素。而高度则从11像素到273像素变化,总共10个anchor.
  • 同时,对于水平的文本行,其中的每一个文本段之间都是有联系的,因此作者采用了CNN+RNN的一种网络结构,检测结果更加鲁棒。

pipeline

整个算法的流程主要有以下几个步骤:(参见下图)

  • 首先,使用VGG16作为base net提取特征,得到conv5_3的特征作为feature map,大小是W×H×C
  • 然后在这个feature map上做滑窗,窗口大小是3×3。也就是每个窗口都能得到一个长度为3×3×C的特征向量。这个特征向量将用来预测和10个anchor之间的偏移距离,也就是说每一个窗口中心都会预测出10个text propsoal。
  • 将上一步得到的特征输入到一个双向的LSTM中,得到长度为W×256的输出,然后接一个512的全连接层,准备输出。
  • 输出层部分主要有三个输出。2k个vertical coordinate,因为一个anchor用的是中心位置的高(y坐标)和矩形框的高度两个值表示的,所以一个用2k个输出。(注意这里输出的是相对anchor的偏移)。2k个score,因为预测了k个text proposal,所以有2k个分数,text和non-text各有一个分数。k个side-refinement,这部分主要是用来精修文本行的两个端点的,表示的是每个proposal的水平平移量。
  • 这是会得到密集预测的text proposal,所以会使用一个标准的非极大值抑制算法来滤除多余的box。
  • 最后使用基于图的文本行构造算法,将得到的一个一个的文本段合并成文本行。

一些细节

vertical anchor

  • k个anchor的设置如下:宽度都是16像素,高度从11~273像素变化(每次乘以1.4)
  • 预测的k个vertical coordinate的坐标如下:
  • 与真值IoU大于0.7的anchor作为正样本,与真值IoU最大的那个anchor也定义为正样本,这个时候不考虑IoU大小有没有到0.7,这样做有助于检测出小文本。
  • 与真值IoU小于0.5的anchor定义为负样本。
  • 只保留score大于0.7的proposal

BLSTM

  • 文章使用了双向的LSTM,每个LSTM有128个隐层
  • 加了RNN之后,整个检测将更加鲁棒,具体效果见下图。上图是加了RNN,下图是没有RNN的结果。

训练

  • 对于每一张训练图片,总共抽取128个样本,64正64负,如果正样本不够就用负样本补齐。这个和faster rcnn的做法是一样的。
  • 训练图片都将短边放缩到600像素。

代码注解

reimplement的github地址

准备训练数据

  • 正如上文所提的,这个网络预测的是一些固定宽度的text proposal,所以真值也应该按照这样来标注。但是一般数据库给的都是整个文本行或者单词级别的标注。因此需要把这些标注转换成一系列固定宽度的box。代码在prepare_training_data这个文件夹。
  • 整个repo是基于RBG大神的faster rcnn改的,所以根据他的输入要求。要再将数据转换为voc的标注形式,这部分代码也在prepare_training_data这个文件夹。

一些预测结果

  • 这个repo没有实现文章中提到的side refinement部分。
  • 以身份证检测做了个例子,但是模型是可以应用到各种水平文本检测的应用中的。
  • 部分检测的结果如下所示:

你可能感兴趣的:(机器学习)