【转载】文本检测之PixelLink
原文:文本检测之PixelLink
地址:https://zhuanlan.zhihu.com/p/38171172
作者:燕小花
文章目录
简介
论文题目:PixelLink: Detecting Scene Text via Instance Segmentation
论文地址:https://arxiv.org/abs/1801.01315
代码实现:https://github.com/ZJULearning/pixel_link
PixelLink放弃了边框回归的思想,采用实例分割的方法,分割出文本行区域,然后直接找对应文本行的外接矩形框.
论文关键idea
- 提出了通过实例分割(Instance Segmentation)来实现文本检测
- 提出了基于DNN的两种pixel-wise预测:文本/非文本预测和link预测
Pipeline
论文中给出了两种网络结构:PixelLink+VGG16 2s和PixelLink+VGG16 4s
对于PixelLink+VGG16 2s网络结构:其融合的特征层包括:{conv2_2, conv3_3, conv4_3, conv5_3, fc_7},得到的特征图分辨率为原图的二分之一
对于PixelLink+VGG16 4s网络结构:其融合的特征层包括:{conv3_3,conv4_3, conv5_3, fc_7},得到的特征图分辨率为原图的四分之一
整个实现过程包括两部分:先通过深度学习网络预测pixel positive和link positive,并根据link positive连接pixel positive得到文本实例分割图,然后从分割图中直接提取文本行的bbox.具体步骤如下:
- 主干网络是沿用了SSD网络结构.具体来说:首先用VGG16作为base net,并将VGG16的最后两个全连接层改成卷积层.
- 提取不同层的feature map,对于PixelLink+VGG16 2s网络结构:提取了conv2_2, conv3_3, conv4_3, conv5_3, fc_7.
- 对已提取的特征层,采用自顶向下的方法进行融合,融合操作包括先向上采样,然后再进行add操作.注意:这里包含了两种操作:pixel cls和pixel link,对应的卷积核个数分别为2和16
- 对于网络输出层,包括文本/非文本预测和Link预测.
这里给出PixelLink+VGG16 2s的网络结构图:
具体实现细节
实例分割和语义分割的区别
先简单介绍下实例分割(Instance Segmentation)和语义分割(Semantic Segmentation)的区别.语义分割对图像中的每个像素都划分出对应的类别,即实现像素级别的分类;而实例分割不但要进行像素级别的分类,还需在具体的类别基础上区别开不同的实例.为了更好地理解语义分割和实例分割,这里给出了具体的示例图(该图来源于https://arxiv.org/pdf/1405.0312.pdf),下图中左下角是语义分割,右下角是实例分割:
连接像素(Linking Pixels Together)
通过设定两个不同的阈值,可以得到pixel positive集合和link positive集合,然后根据link positive将pixel positive进行连接,得到CCs(conected compoents)集合,集合中的每个元素代表的就是文本实例.这里需要特别注意:给定两个相邻的pixel positive,它们之间的link预测是由当前两个pixel共同决定的.而当前两个pixel需要连接(即两个像素属于同一个文本实例)的前提条件:two link中至少有一个link positive.连接的规则采用的是Disjoint set data structure(并查集)的方法.
提取文本行的bounding box
基于上述语义分割的结果(即上述的CCs),直接通过opencv的minAreaRext提取文本的带方向信息的外接矩形框(即带角度信息),具体的格式为((x,y),(w,h),θ),分别表示中心点坐标,当前bbox的宽和高,旋转角度.
这里和SegLink的关键区别:PixelLink是直接从分割结果中提取bbox,而SegLink采用的是边框回归
实例分割的后处理
之所以要进行后处理,是因为在pixel进行连接的时候不可避免地会引入噪声.文中主要是对已检测的bbox通过一些简单的几何形状判断(包括bbox的宽,高,面积及宽高比等,这些主要是在对应的训练集上进行统计的出来的)进行filter.经过后处理后,可以提升文本行检出的准确率.
训练
-
如何生成训练数据的ground truth
像素的生成规则:在文本行bbox内的pixel被标注成positive,如果存在重叠文本时,则非重叠的文本框区域内的像素被标注成positive,否则被标注成negative
像素间的link生成规则:给定一个像素,若其与邻域的8像素都属于同一个文本实例,则将其link标注为positive,否则标注为negative
这里值得注意的是:ground truth的计算是在缩放后(具体缩放的比例与其预测的feature map大小一致)的原图上进行的 -
损失函数
网络的损失函数包含两个部分:pixels loss和links loss,具体的损失函数公式如下:
由于links是在positive pixel基础上进行的预测的,所以这里pixel loss比link loss显得更为重要,论文中将λ=2.0 -
pixel loss
对于positive pixel:由于文本行的aspect ratio变化范围广泛(即文本行的面积各不相等),若在计算loss的时候,对所有的pixel positive给予相同的权重,这对小面积的文本行是非常不公平的(即会偏向大面积的文本行),针对上述问题,论文中提出了Instance-Balanced Cross-Entropy Loss,具体的做法是给每个文本实例相同的权重Bi(公式如下图),对于第i个面积为Si文本实,其内部的每个像素的权重为 w_{i}=\frac{B_{i}}{S_{i}} -
对于negative pixel:论文中采用OHEM来选择negative pixel.具体做法是根据negative-positive比例r (文中设置为3),文本行实例的总面积S,选择loss倒序后的前r*S个negative pixel. 具体的pixel loss公式如下:
其中W为positive pixel和negative pixel的权重矩阵,是文本/非文本的cross-entrpy loss,经过上述公式,小面积的文本行可以得到较大的权重,大面积的文本行得到较小的权重,这样就可以让所有的文本行在loss中贡献一样 -
links loss
论文中只对positive pixel分别计算positive links loss和negative links loss,具体公式如下:
总的link loss是class-balanced cross-entropy loss,具体公式如下: -
网络的输出
网络的输出包括:文本/非文本( 1 x 2 = 2 )和Link预测( 8 x 2=16个),所以对网络总的输出维度为: 2 + 2 x 8 = 18
注意:对于link的输出feature map,其排列的顺序为:top-left,top,top-rignt,left,right,bottom-left,bottom,bottom-right,这里给出一个可视化的顺序图(即下图中的12345678): -
数据增广
数据增广的方式和SSD相似,在SSD数据增广上增加了随机旋转步骤.具体的做法是输入图像先以0.2的概率进行随机旋转,旋转的角度范围值为[0,π=2, π,3π=2];然后在进行crop操作(面积范围在0.1-1之间,aspect ratio为0.5-2);最后统一将图像缩放到 512\times512 .
经过数据增广后,对于文本行的短边小于10个像素的和文本实例小于20%的进行忽略.对于忽略的文本实例在计算损失函数的时候权重设置为0
在ICDAR2015上的评测结果
使用PixelLink训练自己的数据
score map与link map的可视化图
原图:score map
这里所说的score map就是所说的实例分割的得分图,其结果如下:
link map
这里的link map图就是当前像素与其8领域的link得分图,其结果如下:
检测结果
这里给出了几张检测结果图:
总结及困惑
总结
- 与CTPN,EAST,SegLink相比,PixelLink放弃了边框回归方法来检测文本行的bbox,而是采用实例分割方法,直接从分割的文本行区域得到文本行的bbox.PixelLink可以以更少额数据和更快地速度进行训练.
- 假设提取特征的主干网络结构采用VGG16(当然你也可以采用其它主干网络结构),PixelLink不需要在imagenet预训练的模型上进行fine-tuned(即直接从头开始训练),而CTPN,EAST,SegLink都需要在imagenet预训练的模型上进行fine-tuned
- 与CTPN,EAST,SegLink相比,PixelLink对感受野的要求更少,因为每个神经元值只负责预测自己及其邻域内的状态.
- 与SegLink一样,不能检测很大的文本,这是因为link主要是用于连接相邻的segments,而不能用于检测相距较远的文本行
困惑
- 每个神经元只负责自己及其邻域内的状态,而文本行检测中需要考虑上下文信息,这里会不会引入一些false positive?
- 对于后处理模块,虽然简单,但是可能比较依赖训练数据的分布(那些阈值是在其基础上统计出来的),如果训练数据没有很好地覆盖真实应用场景,可能会造成漏检或者误检.
文人文笔粗浅,以上是个人对这篇文章的理解,若有理解错误的地方,欢迎指正.