目录
算法的主要流程
网络模型主要包括三个部分:卷积层、双向LSTM、全连接层
1、VGG16为base net提取特征,将conv5得到feature map输出
2、用3*3滑窗扫描上面得到的feature map,也即在conv5得到的特征上做3*3的滑动窗口:每个点结合周围3*3的区域得到一个长度为3*3*C的特征向量
具体实现如下图,每个点(feature mao)结合周围3*3的区域得到一个长度为3*3*C的特征向量
3、将特征reshape后,输入双向LSTM
CNN学习的是感受野内的空间信息,随着网络的深入,CNN学习到的特征会越来越抽象。对于文本序列检测问题,CNN得到的抽象空间特征,或者说文本本身具有一定的序列特征。
双向LSTM就是将2个方向相反的LSTM相连。
4-1、将Bi-LSTM的输出接入全连接层,作者采用的是三个全连接层分支
论文解析说明:引入了anchor的机制,即对每一个点用k个anchor进行预测,每个anchor就是一个盒子,其高度由[273,...,11]逐渐递减,每次除以0.7(或者反过来每次乘1.4),总共有10个。
设置anchor的目的:
一方面保证在x的方向上,anchor可以覆盖每个点但是又不会互相覆盖;
另一方面,由于不同的文本在y方向上高度差距很大,所以设置10个不同的anchor高度,以保证覆盖不同高度的文本
第一个分支:2k个vertical coordinate(垂直坐标)。
因为一个anchor的纵坐标有两部分组成,分别是中心位置的高(y坐标)和矩形框的高度,所以一个用2k个输出。(注意这里输出的是相对anchor的偏移)
一个anchor的纵坐标有两个:中心位置的高(y坐标)和矩形框的高度
其中
和 分别是预测的坐标和真实的坐标
和 分别是一个anchor的y坐标中心和高度
和 分别是预测出来的y坐标中心和高度
和 分别是真实的y坐标中心和高度
第二个分支:2k个score
因为预测了k个text proposal,所以有2k个分数,text和non-text各有一个分数。(二分类问题,损失函数是softmax)
当分数>0.7,则认为anchor中包含文本
第三个分支:k个side-refinement
这部分主要是用来精修文本行的两个端点的,表示的是每个proposal的水平平移量
其中
是预测出来的距离anchor水平坐标(左或右坐标)最近的坐标
是真实的x坐标
是anchor的x坐标中心
是anchor的宽度,也就是16
4-2、tensotflow代码版本中
在FC后接入RPN网络(类似faster-rcnn),共有两个分支,获得text proposals
(左分子对应上面的分支一,右分支对应上面提到的分支二)
对于得到的anchor
左分支用bounding box regression修正文本的anchor的中心y坐标和高度
右分支用sotfmax来判断anchor是否包含文本,即选出score大的正anchor
具体回归方式见4-1的分析。
anchor经过softmax和y方向的bounding box regression处理后,会得到一组竖条纹的text proposals。
5、文本线构造算法,把分类得到的proposals(细长矩形,score>0.7)合并成为文本线,确定文本检测框
主要思想:每两个相近的proposal组成一个pair,合并不同的pair直到无法再合并(没有公共元素)
主要的步骤:
A、按水平x坐标排序Anchor
B、按规则计算每个Anchor boxi的pair(boxj),组成pair (boxi,boxj)
C、通过pair (boxi,boxj)建立Connect graph,最终获得文本检测框
判断两个proposal,Bi和Bj组成pair的条件
查看下面正向寻找和反向寻找的思想
固定regression的box的宽度和水平位置导致predict的box的水平位置不准确,所以作者引入side-refinement
文中给出了使用side-refinement(红色线)和不使用side-refinement(黄色线)的效果对比图
参考文献 ‘场景文本检测—CTPN原理与实现’ 里举了一个具体的例子,可以帮助理解。
这里附个截图
网络结构分析
输入:N*3*H*W
操作1:VGG16
VGG16 |
卷积核个数 |
卷积核大小 |
Stride/pad |
conv1_1+ReLU |
64 |
3*3 |
1 |
conv1_2+ReLU |
64 |
3*3 |
1 |
maxpool1 |
|
2*2 |
2 |
conv2_1 |
128 |
3*3 |
1 |
conv2_2 |
128 |
3*3 |
1 |
maxpool2 |
|
2*2 |
2 |
conv 3_1 |
256 |
3*3 |
1 |
conv 3_2 |
256 |
3*3 |
1 |
conv 3_3 |
256 |
3*3 |
1 |
maxpool3 |
|
2*2 |
2 |
conv 4_1 |
512 |
3*3 |
1 |
conv 4_2 |
512 |
3*3 |
1 |
conv 4_3 |
512 |
3*3 |
1 |
maxpool4 |
|
2*2 |
2 |
conv 5_1 |
512 |
|
|
conv 5_2 |
512 |
|
|
conv 5_3 |
512 |
|
|
说明:卷积层不改变输入矩阵大小,池化层将长宽变为1/2
输出:N *C *(H/16)*(W/16) = N*512*H*W
操作2:在conv5上做3*3的滑动窗口:每个点结合周围3*3的区域得到一个长度为3*3*C的特征向量
说明:原版caffe用im2col实现,tensorflow中用conv2d代替
输出:N*(3*3*C)*H*W
Reshape:(NH)*W*9C
操作3:以上输出的每一行(NH行)作为一个Tmax=W的数据流送入双向LSTM(隐层神经元128维),学习每一行的序列特征
说明:lstm_out = tf.reshape(lstm_out, [N * H * W, 2 * hidden_unit_num])
输出:(NH)*W *256
说明:outputs = tf.reshape(outputs, [N, H, W, output_channel])
操作4:连接512维的全连接层
输出:N *H*W*512
操作5:连接RPN网络(类似faster-rcnn)
输出:
左分支:N*20*H*W
右分支:N*20*H*W
训练策略
三个分支对应3部分损失函数,得到模型的损失函数
分析:
第一部分Anchor Softmax loss
用于监督学习每个Anchor中是否包含文本,表示是否是Groud truth
第二部分Anchor y coord regression loss
用于监督学习每个包含文本的Anchor的Bouding box regression y方向offset,类似于Smooth L1 loss
其中 Vj 是 Si 中判定为有文本的Anchor(score>0.7),或者与Groud truth vertical IoU>0.5
第三部分side-refinement
用于监督学习每个包含文本的Anchor的Bouding box regression x方向offset,与y方向同理
(这部分在tf版的代码里面并没有实现)
附录链接
论文:Detecting Text in Natural Image with Connectionist Text Proposal Network
原论文开源代码:[code-caffe]
tensorlfow版代码:[code-tensorflow-eragonruan/text-detection-ctpn]
[code-tensorflow-Li-Ming-Fan/OCR-DETETION-CTPN]
参考博文:
ctpn解读(这篇博客里面附的一些资源有很好的参考)
论文阅读学习 - CTPN-Detecting Text in Natural Image with Connectionist Text Proposal Network(附有完整的网络结构)
CTPN项目部分代码学习(部分的代码解析,帮助理解)
CTPN文本检测与tensorflow实现(对Li-Fang-Ming的代码做了一些规整和改动)