这是一篇2017年的文字检测算法框架,有点是不同于传统的Faster rcnn讨论,这个模型直接使用一个FCN模型预测每个点是否是文本行(分类)以及距离文本行边框的距离,然后通过阈值过滤和NMS的方式直接得到最终的文本框。而且可以预测各个方向的文本框。
个人感觉,2019年提出的CenterNet-keypoints有这篇论文的影子。
传统的文本检测模型基本都是pipeline的工作流模式,作者指出他的方法步骤最少。而个人私以为并没有什么特别大的区别,也是按照检测word level box,然后执行过滤和NMS方法。不过实际使用的时候,速度确实是ok的,一张1000*750图片的GPU (型号V100)的处理速度为0.03s,如果通过某些引擎加速,比如tensorRT加速,可以达到0.006s。可以一用。
网络比较突出,令人印象深刻的是,
- 使用的FPN特征金字塔的思路,不断融合低分辨率高信息量和高分辨率低信息量的feature map,最终得到原图1/4大小的一张特征图,对每个像素点进行score分类和box回归预测。
- 在上采样的过程中,不断的缩小channel数量,避免随着分辨率的提高,网络参数过大,占据过多的内存
- 在rbox的预测上,不直接预测box的框的位置,而是去预测其到倾斜矩形的四边距离。(不过这也导致了一个缺点,east无法预测特别长的文本,因为这些信息很难从一个pixel上学习到)
- 在损失函数上,对于位置的预测使用IOU损失。
- 提出了一种简单易行的局部损失函数。
一、 基础网络
基础网络就是stem部分,也就是图中左边部分,这里用的是PVANet,一般也可以使用VGG网络。branch部分灵感来自于FPN,越往上其channel越小,1*1过滤器用于减少channel数量,避免过大的计算量。预测输出部分是下图的右边部分,可以分为两个部分,一个是score输出,不同于以往的二分类,这里只有一个值,表示该像素点是否是文本。文本框位置预测可以是rotate box(RBOX)也可以是QUAD输出。
basenetwork
RBOX输出5个channel,分别是这个文本像素到最小外接矩阵上下左右的距离以及这个AABB(axis-aligned bounding box)轴对其包围盒的旋转角度。
主流上的使用也以RBOX居多。
image.png
对于QUAD输出,则是8个信道的输出,分别为顺时针四个顶点的像素点偏移值,这四个顶点是上图中黄虚线四边形的坐标。
二、标签的生成
文章说要把标签向里缩进0.3
这样做的目的或许是提取到更为准确的信息,不论是人工标注的好与不好,我们按照0.3缩小之后提取的特征都是全部的文本信息。但是这样做也会丢失一些边缘信息,如果按照上述的推断,那么SSD或YOLO都可以这样设计标签了。作者肯定是经过测试的,有好处有坏处吧!
image.png
先进行0.3缩放,这个时候的图就是score
以没缩放的图像为基准,画最小外接矩形,这个外接矩形的角度就是angle。这个大小是缩放的的图大小。感觉直接以score图做角度也一样的。
score图的每个像素点到最小外接矩形的距离为四个location图。
在训练之前,一张图的groundTruth已知的时候,每个pixel的prior值就已经固定了。比如,如果是使用rbox作为预测目标,那么通过对一张图片以及其label的预处理,就知道每个pixel距离上下左右四条边的距离、知道其倾斜角度,知道其score值是0还是1(在标签区域内为1,不在为0)。我们需要预测的也是这些值,损失函数也根据GT和预测结果进行计算。
三、损失函数
1. score loss:
没有使用正负样本均衡和难负样本挖掘的工作,因此也没有这些参数学习的麻烦。为了计算score loss,采用的类别均衡的交叉熵损失
正例的损失函数前有belta参数,belta越大正样本所占的比率就越大。Y*表示ground truth,Y^表示预测的结果。
y*只能取0或者1.因此belta随着正样本的增多而降低。
image.png
2. RBOX loss
对于使用RBOX作为几何输出的情况,损失函数由两个部分组成,分别是
image.png
前者是最小外接矩形框的损失,后者是角度的损失
AABB矩形框需要具备的性质是不因为不同的尺寸而改变,简而言之,就是大的框不会因为大边界而有更大的loss。选择使用IoU损失
image.png
角度使用下面的损失函数
image.png
参数sigma在论文中取10。
3. QUAD loss
如果采用QUAD 8通道输出的方式,那么
image.png
五、局部NMS
这篇文章的另一个亮点就是局部NMS,因为相邻的像素点的几何形状应该是高度相符的,因此按照一行一行的进行融合。按照上面的代码进行。shouldmerge(g,p)表示g和p的IOU大于设定的阈值,weightedmerge(g,p)表示融合之后,位置按照这两个几何体的加权平均得到,score则是两个几何体得分的总和。
image.png其中加权融合的部分
def weighted_merge(g, p):
# 取g,p两个几何体的加权(权重根据对应的检测得分计算得到)
g[:8] = (g[8] * g[:8] + p[8] * p[:8])/(g[8] + p[8])
#合并后的几何体的得分为两个几何体得分的总和
g[8] = (g[8] + p[8])
return g
网友评论