PSENet(渐进式的尺度扩张网络),最新的版本是CVPR 2019的一篇论文,近来18、19年在文本检测领域出现了很多针对“弯曲文本”检测的算法,PSENet就是其中之一(代码开源啦~~)。
目前文本检测领域主要有两种方法,一种是Anchor-based的方法,如下(b)所示,其主要问题是基于anchor的方法很难适用于形状不规则的文本。另一种是segmentation-based的方法,如下©所示,基于语义分割的方法,是从pixel的级别对像素进行分类,理论上来讲其可以检测不规则的文本,但是不容易将相邻的文本区分开来,从而可能会导致多个不同的文本区域被预测为一个。如下(d)是本文提出的PSENet(其本质也是一种改进版的基于语义分割的方法),由图可见,其可以很好的检测不规则的文本并能很好地将其区分开来。
先来总结一下本文的思路:PSENet具体采用的方式是首先预测每个文本行的不同尺度的kernels,这些kernels和原始文本行具有同样的形状,并且中心和原始文本行相同,但是在尺度上是逐渐递增的。最大的kernel就是原始文本行大小。之后对这些kernels采用PSE算法(基于BFS),首先从最小scale的kernel开始,逐步对它进行扩增到更大的kernel,最终扩增到原始文本行大小。而之所以这种方式能够区分文本行边缘像素,是因为对于最小scale的kernel,不同的文本行之间的间距很大,是可以完全分离开的。而在逐渐扩展的过程中是受上一级kernel监督的,因此即使扩增到原始文本行大小也能够将边缘像素区分开来。
文章使用在ImageNet数据集上预训练的Resnet+fpn作为特征提取的网络结构
首先将高层特征和低层特征融合后得到(P2, P3, P4, P5)四个特征层,其中每个特征层的channel数量为256。之后将四个特征层concat得到F, 其中F=C(P2,P3,P4,P5) = P2 || Upx2(P3) || Upx4(P4) || Upx8(P5),其中的||就代表concat。x2,x4,x8分别代表2倍、4倍和8倍的上采样。将F送入Conv(3,3)-BN-ReLU层,并将特征层的channel数量变为256。之后再将F送入多个Conv(1,1)-Up-Sigmod层来得到n个分割结果S1,S2,…Sn(实际上是通过 1 ∗ 1 ∗ n 1*1*n 1∗1∗n卷积得到的),其中的Up代表上采样。
PSE算法的主要思想就是利用BFS(广度优先搜索)算法,逐渐扩展kernel(就是下图中的白色的部分,预测的文本行区域)的大小,最终扩增到原始文本行大小(如S3)。
假设用了3个不同尺度的kernel(如图a,e,f),其中S1(上图a)代表最小kernel的分割结果,它内部有四个连通域C={c1,c2,c3,c4},CC操作得到S1中的四个连通域,得图b(四个连通区域使用不同颜色标记)。现在我们已经得到了图b中的四个连通域(小kernel,不同文本行之间的margin很大,很容易区分开),且我们已知S2中的kernel是比S1中的kernel大的,也就是可以说S2中的kernel是包含S1中的kernel的。现在我们的任务就是将属于S2中的kernel的但不属于S1中的kernel的像素点(即图g左图中的灰色的部分,蓝色和橘色部分分别表示S1中的两个连通域)进行分配。如图所示,在灰色区域(S2的kernel范围)内,将b图所找到的连通域的每个pixel以BFS的方式,逐个向上下左右扩展,即相当于把S1中预测的文本行的区域逐渐变宽(或者换种说法:对于S2中kernel的每个像素点,把它们都分别分配给S1中的某个连通域)。这里还有一个问题,如图g右图所示,图中值为2的点为冲突点,例子中的两个连通域都可能扩展到这个pixel,论文中对这种冲突的解决方法就是“先到先得”原则,这对最后的结果没什么影响。后面的S3同理,最终我们抽取图d中不同颜色标注的连通区域作为最后的文本行检测结果。
渐进式扩展算法的伪代码见下图:
其中T、P代表中间结果,Q是一个队列,Neighbor(.)代表p的相邻像素。GroupByLabel(.)代表根据label对中间结果T进行合并。需要注意的是对于相邻连通区域,在边缘处合并时会产生冲突,因此采用先first-come-first-served的原则,将会产生冲突的像素只合并到一个kernel中去。
这里需要解释一下上图中画红线的部分,if的三个条件分别表示的是:q是p的邻居,q没有被打标签(还没有被扩展到),q是一个前景像素点(在当前的Si预测的kernel内,即扩展是仅在灰色区域内进行的)
首先从网络结构中可以看出,我们需要生成不同尺度的kernel,这是需要有标签的图像来进行训练的。为了生成训练时不同尺寸kernels所对应的ground truths,作者采用Vatti clipping algorithm将原始多边形pn缩放di个像素从而得到pi,其中每个缩放的pi都是使用0/1的二进制mask来表示分割后的标签的。
假设缩放的比例为ri,则pn和pi之间的margin di为:
其中Area(.)代表多边形的面积,而Perimeter(.)代表多边形的周长。
对于ri的定义为:
其中n是不同尺度的kernel的个数(即S1,S2,…,Sn),m代表最小的缩放比例,值的范围为(0,1]。由上面两式可以看出,ri由超参数n和m来决定,当i=1时,r1为m,当i=n时,rn为1,因此ri的取值范围为[m,1]。
注:论文中取的n=6,m=0.5(即S1的kernel的大小是原始文本行大小的一半)。
损失函数定义为:
损失函数分为两部分,其中Lc和Ls分别代表整个文本实例(Sn)和缩放后文本实例(S1 -> Sn-1)的损失,而λ用于平衡Lc和Ls,这里设置为0.7。
通常文本实例可能只占自然场景很小的一部分,因此如果采用二进制交叉熵损失会造成预测结果更加偏向于非文本区域。这里我们采用dice coefficient损失函数:
其中Si,x,y和Gi,x,y分别代表分割结果Si和ground truth Gi的(x,y)位置处的像素值。(开源的East代码也使用这种损失函数,确实比交叉熵损失效果要好)
考虑到很多文本区域和栅栏、栅格很相似,为了避免误检,这里采用了OHEM来更好的对文本区域进行区分,其中负样本-正样本的比例设置为3:1。
首先来看Lc的计算方式:
其中M代表OHEM的training mask,Lc主要用于区分文本和非文本区域。
再来看Ls的计算方式:
Ls主要是shrink文本区域的损失,考虑到shrink后的文本区域被原始文本区域包围,因此作者忽略了分割结果Sn中非文本区域的像素从而避免像素冗余的情况。其中W代表Sn中文本区域的mask,Sn,x,y代表Sn中(x,y)的像素值。
到这里PSENet已经差不多讲完,接下来我们看看PSENet在不同数据集上的表现,如Table 1所示,PSENet在常规数据集ICDAR 2015和ICDAR 2017 MLT上的表现不弱于主流的检测算法,但在弯曲文字数据集SCUT-CTW1500上的表现超过了之前最好的结果6.37%。下图是PSENet在不同数据集上的一些结果。
欢迎大家多多交流,共同进步~