场景文字检测—CTPN原理与实现

场景文字检测—CTPN原理与实现

对于复杂场景的文字识别,首先要定位文字的位置,即文字检测。这一直是一个研究热点。

Detecting Text in Natural Image with Connectionist Text Proposal Networkarxiv.org

CTPN是在ECCV 2016提出的一种文字检测算法。CTPN结合CNN与LSTM深度网络,能有效的检测出复杂场景的横向分布的文字,效果如图1,是目前比较好的文字检测算法。

图1 场景文本检测

由于CTPN是从Faster RCNN改进而来,本文默认读者熟悉CNN原理和Faster RCNN网络结构。否则建议首先阅读本专栏文章:

一文读懂Faster RCNNzhuanlan.zhihu.com图标

CTPN相关:

caffe代码:

tianzhi0549 - Overviewgithub.com图标

tensorflow代码:

eragonruan/text-detection-ctpngithub.com图标

CTPN网络结构

原始CTPN只检测横向排列的文字。CTPN结构与Faster R-CNN基本类似,但是加入了LSTM层。假设输入 N Images:

  • 首先VGG提取特征,获得大小为 N \times C\times H\times W 的conv5 feature map。
  • 之后在conv5上做 3×3 的滑动窗口,即每个点都结合周围 3×3 区域特征获得一个长度为 3×3×C 的特征向量。输出 N \times9C\times H\times W 的feature map,该特征显然只有CNN学习到的空间特征。
  • 再将这个feature map进行Reshape

\text{Reshape:} \ N\times 9C\times H \times W \rightarrow (NH) \times W \times 9C\\

  • 然后以 \text{Batch}=NH 且最大时间长度 T_\text{max}= W 的数据流输入双向LSTM,学习每一行的序列特征。双向LSTM输出 (NH) \times W\times 256 ,再经Reshape恢复形状:

\text{Reshape:}\  (NH)  \times W \times 256\rightarrow N \times256\times H\times W\\

该特征既包含空间特征,也包含了LSTM学习到的序列特征。

  • 然后经过“FC”卷积层,变为 N \times512\times H\times W 的特征
  • 最后经过类似Faster R-CNN的RPN网络,获得text proposals,如图2-b。
图2 CTPN网络结构

更具体的网络结构,请使用netscope查看CTPN的deploy.prototxt网络配置文件。

这里解释一下conv5 feature map如何从N \times C\times H\times W 变为N \times9C\times H\times W

在原版caffe代码中是用im2col提取每个点附近的9点临近点,然后每行都如此处理:

H\times W\rightarrow9 \times H \times W \\

接着每个通道都如此处理:

C\times H\times W\rightarrow9C \times H \times W \\

而im2col是用于卷积加速的操作,即将卷积变为矩阵乘法,从而使用Blas库快速计算。到了tf,没有这种操作,所以一般是用conv2d代替im2col,即强行卷积 C\rightarrow9C

接下来,文章围绕下面三个问题展开:

  1. 为何使用双向LSTM
  2. 如何通过FC层输出产生图2-b中的Text proposals
  3. 如何通过Text proposals确定最终的文本位置,即文本线构造算法

为何使用双向LSTM?

  • 对于RNN原理不了解的读者,请先参考RNN原理介绍:
完全解析RNN,Seq2Seq和Attention机制zhuanlan.zhihu.com图标
  • 关于LSTM长短期记忆模型,请参考
Understanding LSTM Networkscolah.github.io图标
  • CTPN中为何使用双向LSTM?

首先,CTPN中为何使用LSTM?

图e CNN卷积计算示意图

CNN学习的是感受野内的空间信息,LSTM学习的是序列特征。对于文本序列检测,显然既需要CNN抽象空间特征,也需要序列特征(毕竟文字是连续的)。

CTPN中使用双向LSTM,相比一般单向LSTM有什么优势?双向LSTM实际上就是将2个方向相反的LSTM连起来,如图r。

图r BLSTM

一般来说,双向LSTM都好于单向LSTM。还是看LSTM介绍文章中的例子:

我的手机坏了,我打算____一部新手机。

假设使用LSTM对空白部分填词。如果只看横线前面的词,“手机坏了”,那么“我”是打算“修”还是“买”还是“大哭一场”?双向LSTM能看到后面的词是“一部新手机“,那么横线上的词填“买“的概率就大得多了。显然对于文字检测,这种情况也依然适用。

如何通过"FC"卷积层输出产生图2-b中的Text proposals?

图5 CTPN的RPN网络

CTPN通过CNN和BLSTM学到一组“空间 + 序列”特征后,在"FC"卷积层后接入RPN网络。这里的RPN与Faster R-CNN类似,分为两个分支:

  1. 左边分支用于bounding box regression。由于fc feature map每个点配备了10个Anchor,同时只回归中心y坐标与高度2个值,所以rpn_bboxp_red有20个channels
  2. 右边分支用于Softmax分类Anchor

具体RPN网络与Faster R-CNN完全一样,所以不再介绍,只分析不同之处。

竖直Anchor定位文字位置

由于CTPN针对的是横向排列的文字检测,所以其采用了一组(10个)等宽度的Anchors,用于定位文字位置。Anchor宽高为:

 \text{widths} = [16]\\

\text{heights}=[11, 16, 23, 33, 48, 68, 97, 139, 198, 283]\\

需要注意,由于CTPN采用VGG16模型提取特征,那么conv5 feature map的宽高都是输入Image的宽高的 1/16

同时fc与conv5 width和height都相等。

如图6所示,CTPN为fc feature map每一个点都配备10个上述Anchors。

图6 CTPN Anchor

这样设置Anchors是为了:

  1. 保证在 x 方向上,Anchor覆盖原图每个点且不相互重叠。
  2. 不同文本在 y 方向上高度差距很大,所以设置Anchors高度为11-283,用于覆盖不同高度的文本目标。

多说一句,我看还有人不停的问Anchor大小为什么对应原图尺度,而不是conv5/fc特征尺度。这是因为Anchor是目标的候选框,经过后续分类+位置修正获得目标在原图尺度的检测框。那么这就要求Anchor必须是对应原图尺度!除此之外,如果Anchor大小对应conv5/fc尺度,那就要求Bounding box regression把很小的框回归到很大,这已经超出Regression小范围修正框的设计目的。

获得Anchor后,与Faster R-CNN类似,CTPN会做如下处理:

  1. Softmax判断Anchor中是否包含文本,即选出Softmax score大的正Anchor
  2. Bounding box regression修正包含文本的Anchor的中心y坐标高度

注意,与Faster R-CNN不同的是,这里Bounding box regression不修正Anchor中心x坐标和宽度。具体回归方式如下:

其中, v=(v_c, v_h) 是回归预测的坐标, v=(v_c^*, v_h^*) 是Ground Truth, c_y^ah^a 是Anchor的中心y坐标和高度。Bounding box regression具体原理请参考之前文章。

Anchor经过上述Softmax和 y 方向bounding box regeression处理后,会获得图7所示的一组竖直条状text proposal。后续只需要将这些text proposal用文本线构造算法连接在一起即可获得文本位置。

图7 Text proposal

在论文中,作者也给出了直接使用Faster R-CNN RPN生成普通proposal与CTPN LSTM+竖直Anchor生成text proposal的对比,如图8,明显可以看到CTPN这种方法更适合文字检测。

图8

文本线构造算法

在上一个步骤中,已经获得了图7所示的一串或多串text proposal,接下来就要采用文本线构造办法,把这些text proposal连接成一个文本检测框。

图9

为了说明问题,假设某张图有图9所示的2个text proposal,即蓝色和红色2组Anchor,CTPN采用如下算法构造文本线:

  1. 按照水平 x 坐标排序Anchor
  2. 按照规则依次计算每个Anchor \text{box}_i\text{pair}(\text{box}_j) ,组成 \text{pair}(\text{box}_i, \text{box}_j)
  3. 通过 \text{pair}(\text{box}_i, \text{box}_j) 建立一个Connect graph,最终获得文本检测框

下面详细解释。假设每个Anchor index如绿色数字,同时每个Anchor Softmax score如黑色数字。

文本线构造算法通过如下方式建立每个Anchor \text{box}_i \text{pair}(\text{box}_i, \text{box}_j)

正向寻找:

  1. 沿水平正方向,寻找和 \text{box}_i 水平距离小于50的候选Anchor
  2. 从候选Anchor中,挑出与 \text{box}_i 竖直方向 \text{overlap}_v >0.7 的Anchor
  3. 挑出符合条件2中Softmax score最大的 \text{box}_j

再反向寻找:

  1. 沿水平负方向,寻找和 \text{box}_j 水平距离小于50的候选Anchor
  2. 从候选Anchor中,挑出与 \text{box}_j 竖直方向 \text{overlap}_v >0.7 的Anchor
  3. 挑出符合条件2中Softmax score最大的 \text{box}_k

最后对比 \text{score}_i\text{score}_k :

  1. 如果 \text{score}_i >= \text{score}_k ,则这是一个最长连接,那么设置 \text{Graph}(i, j) = \text{True}
  2. 如果 \text{score}_i < \text{score}_k ,说明这不是一个最长的连接(即该连接肯定包含在另外一个更长的连接中)。
图10 构造文本线

举例说明,如图10,Anchor已经按照 x 顺序排列好,并具有图中的Softmax score(这里的score是随便给出的,只用于说明文本线构造算法):

  1. 对于 i=3\text{box}_3 ,向前寻找50像素,满足 \text{overlap}_v>0.7 且score最大的是 \text{box}_7 ,即 j=7\text{box}_7 反向寻找,满足 \text{overlap}_v >0.7 且score最大的是 \text{box}_3 ,即 k=3 。由于 \text{score}_3 >= \text{score}_3\text{pair}(\text{box}_3, \text{box}_7) 是最长连接,那么设置 \text{Graph}(3,7) = \text{True}
  2. 对于 \text{box}_4 正向寻找得到 \text{box}_7\text{box}_7 反向寻找得到 \text{box}_3 ,但是 \text{score}_4 < \text{score}_3 ,即 \text{pair}(\text{box}_4, \text{box}_7) 不是最长连接,包含在 \text{pair}(\text{box}_3, \text{box}_7) 中。

然后,这样就建立了一个 N\times N 的Connect graph(其中 N 是正Anchor数量)。遍历Graph:

  1. \text{Graph}(0,3) = \text{True}\text{Graph}(3,7) = \text{True} ,所以Anchor index 1->3->7组成一个文本,即蓝色文本区域。
  2. \text{Graph}(6,10) = \text{True}\text{Graph}(10,12) = \text{True} ,所以Anchor index 6->10->12组成另外一个文本,即红色文本区域。

这样就通过Text proposals确定了文本检测框。

训练策略

由于作者没有给出CTPN原始训练代码,所以此处仅能根据论文分析。

Loss(s_i,v_j,o_k)=\frac{1}{N_s}\sum_{i}^{}{L_s^{cls}(s_i,s_i^*)+\frac{\lambda_1}{N_v}}\sum_{j}^{}{L_v^{reg}(v_j, v_j^*) +\frac{\lambda_2}{N_o}\sum_{k}^{}{L_o^{reg}(o_k, o_k^*)}}

明显可以看出,该Loss分为3个部分:

  1. Anchor Softmax loss:该Loss用于监督学习每个Anchor中是否包含文本。 s_i^*=\{0,1\} 表示是否是Groud truth。
  2. Anchor y coord regression loss:该Loss用于监督学习每个包含为本的Anchor的Bouding box regression y方向offset,类似于Smooth L1 loss。其中 v_js_i 中判定为有文本的Anchor,或者与Groud truth vertical IoU>0.5。
  3. Anchor x coord regression loss:该Loss用于监督学习每个包含文本的Anchor的Bouding box regression x方向offset,与y方向同理。前两个Loss存在的必要性很明确,但这个Loss有何作用作者没有解释(从训练和测试的实际效果看,作用不大)

说明一下,在Bounding box regression的训练过程中,其实只需要注意被判定成正的Anchor,不需要去关心杂乱的负Anchor。这与Faster R-CNN类似。

总结

  1. 由于加入LSTM,所以CTPN对水平文字检测效果超级好。
  2. 因为Anchor设定的原因,CTPN只能检测横向分布的文字,小幅改进加入水平Anchor即可检测竖直文字。但是由于框架限定,对不规则倾斜文字检测效果非常一般。
  3. CTPN加入了双向LSTM学习文字的序列特征,有利于文字检测。但是引入LSTM后,在训练时很容易梯度爆炸,需要小心处理。


推荐一篇蛮不错的场景文字检测综述:

白翔:趣谈“捕文捉字”-- 场景文字检测 | VALSE2017之十mclab.eic.hust.edu.cn

关于想了解后续文字识别的读者,欢迎参考本专栏文章:

一文读懂CRNN+CTC文字识别zhuanlan.zhihu.com图标

编辑于 2019-07-19

文章被以下专栏收录