最近研究OCR,有篇比较好的算法文章,《EAST: An Efficient and Accurate Scene Text Detector》,该文发表在2017年CVPR上。代码地址:https://github.com/argman/EAST ,这是原作者参与的一份tensorflow版本代码,网上还有其他的实现。
下面根据原文的结构和上述提供的代码详细的解读一下该算法
文中使用了PVANet和VGG16,下图1是原文的网络结构图(PVANet)
网络输入一张图片,经过四个阶段的卷积层可以得到四张feature map, 分别为 f 4 , f 3 , f 2 , f 1 f_{4},f_{3},f_{2},f_{1} f4,f3,f2,f1,它们相对于输入图片分别缩小 1 4 , 1 8 , 1 16 , 1 32 \frac{1}{4},\frac{1}{8},\frac{1}{16},\frac{1}{32} 41,81,161,321,之后使用上采样、concat(串联)、卷积操作依次得到 h 1 , h 2 , h 3 , h 4 h_{1},h_{2},h_{3},h_{4} h1,h2,h3,h4,在得到 h 4 h_{4} h4这个融合的feature map后,使用大小为 3 × 3 3\times3 3×3通道数为32的卷积核卷积得到最终的feature map。
文中对文本框的定义有两种,一种是旋转矩形(RBOX),另一种是四边形(QUAD)。因为代码只实现了RBOX,所以下面也只对RBOX框进行分析
得到最终的feature map后,使用一个大小为 1 × 1 1\times1 1×1通道数为1的卷积核得到一张score map用 F s F_{s} Fs表示。在feature map上使用一个大小为 1 × 1 1\times1 1×1通道数为4的卷积核得到text boxes,使用一个大小为 1 × 1 1\times1 1×1通道数为1的卷积核得到text rotation angle,这里text boxes和text rotation angle合起来称为geometry map用 F g F_{g} Fg表示。
关于上述的 F s , F g F_{s},F_{g} Fs,Fg要说明几点(如下图2所示):
如上可知,训练标签由两个部分组成,一个是score map的标签,一个是geometry map标签。
注意:程序要求输入的四边形标定点是以顺时针方向标定的,这点很重要
1. score map标签的生成方法
上述缩小四边形的方法:
2. geometry map标签的生成方法
损失函数定义如下
L = L s + λ g L g L = L_{s} + \lambda_{g}L_{g} L=Ls+λgLg
其中 L s L_{s} Ls和 L g L_{g} Lg分别表示score map和geometry map的损失, λ g \lambda_{g} λg表示两个损失的权重,文章设为1
1. score map的损失计算
这里要说明的是文章采用的是交叉熵计算该损失,但是程序实现没有采用,程序采用的是dice loss
L s = 1 − 2 y s p s y s + p s L_{s}=1-\frac{2y_{s}p_{s}}{y_{s}+p_{s}} Ls=1−ys+ps2ysps
其中 y s y_{s} ys代表位置敏感图像分割(position-sensitive segmentation)的label, p s p_{s} ps代表预测的分割值
2. geometry map的损失计算
采用IoU loss,计算方法如下
L g = L A A B B + λ θ L θ L_{g} = L_{AABB} + \lambda_{\theta}L_{\theta} Lg=LAABB+λθLθ
其中 λ θ = 10 \lambda_{\theta}=10 λθ=10
L A A B B = − l o g I o U ( R ^ , R ) = − l o g ∣ R ^ ⋂ R ∗ ∣ ∣ R ^ ⋃ R ∗ ∣ L_{AABB}=-logIoU(\hat{R},R)=-log\frac{|\hat{R}\bigcap R^{*}|}{|{\hat{R}\bigcup R^{*}}|} LAABB=−logIoU(R^,R)=−log∣R^⋃R∗∣∣R^⋂R∗∣
其中, R ^ \hat{R} R^表示预测, R ∗ R^{*} R∗表示真实值
∣ R ^ ⋂ R ∗ ∣ = w i ∗ h i |\hat{R}\bigcap R^{*}|=w_{i}*h_{i} ∣R^⋂R∗∣=wi∗hi计算可以通过下述方法
w i = m i n ( d 2 ^ , d 2 ∗ ) + m i n ( d 4 ^ , d 4 ∗ ) w_{i}=min(\hat{d_{2}}, d^{*}_{2})+min(\hat{d_{4}}, d^{*}_{4}) wi=min(d2^,d2∗)+min(d4^,d4∗)
h i = m i n ( d 1 ^ , d 1 ∗ ) + m i n ( d 3 ^ , d 3 ∗ ) h_{i}=min(\hat{d_{1}}, d^{*}_{1})+min(\hat{d_{3}}, d^{*}_{3}) hi=min(d1^,d1∗)+min(d3^,d3∗)
其中 d 1 , d 2 , d 3 , d 4 d_{1},d_{2},d_{3},d_{4} d1,d2,d3,d4表示点到top、right、bottom、left边的距离。
∣ R ^ ⋃ R ∗ ∣ = ∣ R ^ ∣ + ∣ R ∗ ∣ − ∣ R ^ ⋂ R ∗ ∣ |{\hat{R}\bigcup R^{*}}|=|\hat{R}|+|R^{*}|-|\hat{R}\bigcap R^{*}| ∣R^⋃R∗∣=∣R^∣+∣R∗∣−∣R^⋂R∗∣
L θ ( θ ^ , θ ∗ ) = 1 − c o s ( θ ^ − θ ∗ ) L_{\theta}(\hat{\theta}, \theta^{*})=1-cos(\hat{\theta}-\theta^{*}) Lθ(θ^,θ∗)=1−cos(θ^−θ∗),其中 θ ∗ \theta^{*} θ∗表示预测值, θ ^ \hat{\theta} θ^表示真实值
最后文章还提出了Locality-Aware NMS,感觉就是先合并一次窗口,然后采用标准的NMS去抑制窗口,详细可以看代码实现,采用的是c++实现的
中文本定位与识别的评测方法
欢迎加入OCR交流群:785515057