ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

EAST文本检测算法全解析:原理、训练与OCR落地实践

EAST文本检测算法全解析:原理、训练与OCR落地实践 场景文本检测这块我前前后后折腾了不少算法从最早基于滑动窗口的CTPN到后来基于分割的PixelLink、PSENet再到各种Transformer方案兜兜转转一圈发现EAST(Efficient and Accurate Scene Text Detector)这个2017年CVPR上的工作依然是很多实际项目里性价比最高的起点。虽然现在看起来定位不如DB、DBNet那些新方案强势但EAST在整个OCR链路里所扮演的角色以及它背后的设计思想非常值得掰开揉碎讲一讲。聊聊我对EAST的理解和实践经验包括网络结构怎么拆、损失函数为什么这么设计、训练时最容易翻车的几个细节以及这套东西放在2024年的今天还能用在哪些场景里。如果你正准备做车牌识别、票据信息抽取、或者任意方向文本行的检测这篇文章应该能帮你省下不少试错的时间。1. 场景文本检测的三个核心痛点与EAST的解题思路1.1 自然场景的文字和文档扫描件完全是两回事先聊一个最基础的问题为什么自然场景文本检测这么难拿一张文档扫描件来说文字基本是水平的背景是纯净的白纸行与行之间的间距很规整这种场景下最老套的投影法、连通域分析都能做到极高的准确率。但自然场景完全是另一个物种路边的广告牌有透视畸变的士车身上的电话倾斜了30度店铺招牌上有各种艺术字体形状更别提逆光、树木遮挡、夜间反光这些光照问题。如果一个检测算法只对水平文本有效那它能覆盖的实际场景大概不到一半。EAST最核心的一个出发点就是检测目标必须支持任意方向的四边形而不是传统的axis-aligned矩形框。它不依赖文本行内部的字符级标注直接在文本行级别输出带方向的包围盒。这一点和当时的CTPN有本质的区别。CTPN的思路是先把文本切成一个个小垂直锚点再用BLSTM串起来最后通过后处理把小的文本框拼接成完整的文本行。这种先检测局部再组合全局的方式在长文本场景下经常出问题拼接过程中一旦某个锚点漏检整行文本就断了。而EAST的思路很直接我不做中间过程把整行文本作为一个完整的目标直接回归它的几何属性。这个理念用一句话概括就是“端到端”。1.2 一个直接回归文本行的思路EAST的整体思想非常直白把文本检测定位成一个全卷积网络直接回归任务。网络输入的是一张图输出的是两个分支一个score map表示每个像素属于文本的概率另一个geometry map表示这个位置的文本几何信息旋转矩形或者任意四边形。这里最关键的突破在于它把“如何组织文本区域”这件事从多阶段的pipeline中完全解放出来。传统方法需要先生成候选框、再筛选、再回归而EAST通过全卷积网络直接在像素级做密集预测最终只需要通过阈值的筛选和NMS后处理就能拿到完整的文本行框。这种简洁的设计在当年给了场景文本检测一个非常优秀的baseline也奠定了后续很多算法的基本范式。这个算法解决什么样的问题简单总结就是三件事检测速度要足够快能够支撑实时应用能够支持任意方向的文本行检测能够适应自然场景中各种复杂的背景和光照条件。2. EAST网络结构全拆解从特征融合到几何输出的完整链路2.1 共享特征提取主干与特征金字塔的多级融合EAST的主干网络原论文用的是PVANet一个在当年以轻量和高性能著称的backbone。后续大家复现的时候用VGG16、ResNet50替换的也很多因为PVANet的预训练权重不太好找而VGG16的权重几乎随处可得。不过无论用哪种backboneEAST的网络结构本质上分为三个部分特征提取层、特征融合层、输出层。特征提取层的作用不言而喻负责从原始图像中提取丰富的语义信息和空间信息。EAST沿用了特征金字塔的核心思想选取主干网络中的四个尺度的特征图从浅层的细节特征对应高分辨率到深层的语义特征对应低分辨率。具体来说是conv1_2、conv2_2、conv3_3、conv4_3这些层ResNet对应的是stage2到stage5的输出。关键在特征融合这个环节这个设计在当年非常有特色。EAST没有采用FPN那种简单的自上而下加和而是采用了自下而上的逐级融合策略。具体来看从最深层的feature map开始通过上采样把它与前一层的高分辨率特征拼接起来再通过一个1x1卷积降通道、一个3x3卷积融合得到融合后的特征。这个过程逐层往下重复最终得到一个同时具备高分辨率空间信息和强语义信息的特征层。这里为什么要这样设计原因在于文本检测这个任务对空间位置极其敏感文本边界越精细检测框越准确。深层特征经过多次下采样已经丢失了太多细节光靠深层特征不可能回归出精确的四边形边缘。而浅层特征虽然保留了边界细节但语义信息不足容易把路面纹理、窗框边缘这种图形误判成文字。所以必须把两者结合起来。EAST的融合策略比同时期FPN更激进融合次数更多效果也更好。2.2 输出层如何同时预测置信度与几何属性融合后的特征进入输出层输出层分成两个分支一个分支负责生成score map单通道每个像素表示该位置是文本中心区域的概率另一个分支生成geometry map根据你要检测的文本形状需求分为两种模式。第一种是RBOXRotated Box输出5个通道分别是该像素到文本旋转矩形上、右、下、左四条边的距离外加一个旋转角度theta。第二种是QUADQuadrangle输出8个通道对应任意四边形的四个顶点坐标每个顶点x和y各一个通道。实际应用中RBOX的使用率远远大于QUAD因为大多数场景文本虽然方向各异但基本上还是可以近似为旋转矩形的。QUAD的8通道回归难度更大训练起来也更容易发散除非你的文本是那种极端的梯形、平行四边形否则我不太建议一上来就上QUAD。输出层的设计里有个很细节的地方论文里对RBOX的5个通道使用了不同尺寸的卷积核来生成score map用128通道的1x1卷积而geometry map也类似这样做的原因是两类输出对感受野的需求不同分类任务更看重局部纹理回归任务需要更充分的上下文信息。2.3 局部感知NMSEAST的提速关键后处理阶段EAST对score map设定一个阈值原论文是0.8把置信度较低的预测像素丢掉剩下的保留。但这时每个像素都预测了一个旋转矩形直接对所有候选框做全局NMS的话计算量是灾难级的。EAST提出了一种叫Local-Aware NMS局部感知NMS的近似方案。它的核心思路是分两步走先将每个像素的预测几何体按行合并具体做法是按行遍历时同一行中相邻的几何体如果IoU超过阈值原论文默认0.7就把它们的坐标加权平均合并成一个大的几何体之后再对合并后的几何体做标准的NMS。这样候选框的数量从像素级别减少到了文本行级别NMS的计算量大幅下降整体速度能提升好几倍。实测中这个设计非常关键如果直接对全图几万个候选框做标准NMS整个检测流程的耗时会被拖慢到完全不可用。提示局部感知NMS里的“按行合并”依赖一个前提即文本像素预测的几何体在空间上是相邻的这个前提在文本行间距比较正常的时候成立。如果场景里文本行非常密集不同行的几何体互相交叉合并时容易把两行文本混成一个框这个算EAST的一个先天缺陷后面我会详细说。3. 训练一个自己的EAST模型数据生成、损失函数与学习率细节3.1 从四边形标注到RBOX的groundtruth生成EAST训练最容易被忽略的一步是groundtruth的生成。标注人员给你的往往是任意四边形坐标四个点但RBOX模式要求的训练目标是一个旋转矩形加一个角度的表示所以你需要自己写一个把四边形转成旋转矩形的流程。最简单的方式是用OpenCV的minAreaRect函数对四边形的四个顶点直接求最小外接旋转矩形。这个函数返回旋转矩形的中心点坐标、宽高和角度。有了旋转矩形后相对该旋转矩形内部的每个像素到四条边的距离d1、d2、d3、d4就构成了geometry的一部分。有一件事很多人没注意到score map的groundtruth不能简单地用整个文本框内全部置1。原论文的做法是对原始的标注多边形做0.3倍边的收缩按面积收缩只保留中间的核心区域。这个操作的目的是避免相邻文本实例的score map重叠在一起确保靠近边界但其实是相邻文本的那些像素不会被当成一个正样本。这个细节对于文本行间距较密的数据集至关重要。如果不做收缩训练出来的模型会把相邻两行文字连成一片输出一个包含两行的完整大框。3.2 分类损失采用Dice Loss的深层原因EAST在分类支路score map使用的损失函数不是常规的交叉熵而是Dice Loss。论文里的公式是L_s 1 - (2 * |P ∩ G|) / (|P| |G|)用文字解释就是预测的文本区域和实际groundtruth的交集的两倍除以两者的面积之和再用1减去。这个损失函数的本质是在优化Dice系数Dice系数衡量的是两个集合的相似度对前景和背景数量不平衡的问题有天然的抗性。文本检测任务里正样本文本像素在整幅图里占比通常很低尤其是在自然场景图片中密密麻麻的背景像素如果全部用交叉熵来约束模型会倾向于把所有像素都预测为背景loss依然很小但实际上一个文本区域都检测不出来。Dice Loss因为分母涉及预测区域与真实区域的并集让模型必须同时关注precision和recall即便正样本极少也能稳定优化。在EAST里分类损失还另外加了一个负样本权重损失公式里对负样本乘了3.0进一步避免背景压倒前景。3.3 回归损失中的IoU Loss与角度损失的周期性陷阱RBOX模式的几何回归损失分成两部分框的IoU损失和角度的余弦损失。IoU损失定义为 L_A -log(IoU(预测旋转矩形, 真实旋转矩形))。用负的ln来放大IoU较低时的梯度让模型在初期快速修正粗偏差。为什么不用smooth L1直接回归四个距离因为四个距离之间是相互关联的独立回归一个坐标值会导致矩形形状不合理IoU Loss直接度量预测框和真实框之间的重叠程度优化目标和最终的评价指标一致训练更高效。角度损失部分需要特别警惕一个坑。角度的周期性导致0度和180度其实是同一个方向如果用L1或者L2这类距离直接回归角度差在角度跨越边界时会产生一个巨大的梯度跳变模型怎么学也学不收敛。EAST的处理方式是用 L_theta 1 - cos(theta - theta*) cos函数天然周期且连续角度越接近目标值损失越小。这个细节在做工程复现的时候很多人会忽略直接用smooth L1回归角度结果训练一阵子发现loss在震荡怎么都降不下去原因就在这。3.4 训练过程中的超参数设置参考我复现的时候主要参考论文里的默认配置直接说结论输入图像尺寸随机在224x224到512x512之间采样长边不超过512优化器Adam学习率初始1e-3每27300次迭代衰减为原来的十分之一Batch size论文用24我实践下来显存不够的话8到16也能跑损失曲线一样能收敛训练轮数大约100个epochICDAR2015这种中等规模数据集上1080Ti单卡跑一整天左右数据增强随机旋转角度在-10度到10度、随机裁剪、随机缩放、颜色扰动我自己的使用体验是训练完的model对水平文本的检测效果非常优秀对倾斜文本的效果取决于训练数据里的角度分布。如果你的场景里文本方向跨度大建议数据增强里加大旋转角度的范围或者干脆对训练样本做透视变换模拟自然场景里常见的拍摄角度。4. 复现EAST时最容易翻车的几个环节与实测调优经验4.1 主干网络的预训练权重选择先看代码层面最基础的选型。原论文用PVANet但PVANet是腾讯出品的一个轻量网络代码是Caffe风格想直接迁移到PyTorch的生态里其实挺折腾。我在实际训练中换成了ResNet50作为主干保留其在ImageNet上的预训练权重最后的效果在原论文报告的基线水平之上。VGG16也可以但VGG16参数量太大训练速度会明显变慢。如果你显存吃紧可以试试用MobileNetV3或者EfficientNet的小模型但要注意调整特征金字塔的通道对齐不然拼接的时候维度不匹配会报错。一个容易被忽略的问题是加载预训练权重后需要把batch norm层设置为train模式。很多人在迁移学习时习惯把bn层冻结但在EAST这种密集预测任务里bn层不更新会导致训练曲线非常奇怪loss像过山车一样大起大落。我踩过这个坑冻结bn时训练了几个epoch验证集score map一片模糊解冻后立刻恢复正常。4.2 尺度问题小文本长期漏检怎么办EAST对目标尺寸非常敏感。小文本对应到feature map上可能只有几个像素特征金字塔融合后在高分辨率层还有一些细节但整体上对小目标仍然不友好。如果你用512x512分辨率训练测试时输入的图像超过这个尺寸一定要先把图像resize到合适范围再送入网络否则大量的模型性能浪费在无效区域上。实践中如果发现小文本漏检率高优先尝试的不应该是无脑上Transformer而是把训练图像的随机尺度下限调低比如224降到160这样模型能见到更小的文本实例。还可以在测试阶段使用图像金字塔把同一张图以多个尺度分别推理对不同尺度的结果做合并NMS。这个方法虽然笨但效果非常扎实尤其适合那种文本大小跨度极大的街景图。4.3 文本行间距过密时的score map收缩策略EAST有一个出名的硬伤当文本行间距很小甚至行与行之间几乎没有间隔时score map的收缩策略和RBOX的预测都可能出现问题。收缩策略如果固定为0.3倍一些超长文本行的中间部分相对较窄收缩后核心区域可能太小正样本数量不足导致训练出的score map在长文本中间出现空洞检测结果变成上下两段中间断开。这种情况我遇到过好几次特别是检测一长串超市小票上的商品名时断框的频率特别高。一个实用的调优方案是改用动态收缩比例对于短边较长的四边形收缩比例适当调大一些对于本身就是超窄长条形的文本收缩比例调小到0.1到0.2。具体数值需要根据你的数据分布做实验。另外后处理时可以对score map先做一次小核膨胀操作把可能出现的细裂缝连接起来能显著减少断框。4.4 关于角度回归与长文本断裂的实测观察角度回归的难点在于边界值附近。如果一个文本框真实角度是89度模型预测了-89度实际只差2度但数值上相差178度用普通的L1损失会被放大几十倍的梯度。虽然原论文用cos损失解决了周期性部分但工程实现时还需要注意角度归一化的方向一致性。长文本断裂是我实际使用中遇到最多的问题。根源在于EAST的输出层感受野是有限的对于跨度过长的文本行单个像素能看到的上下文范围有限无法准确判断整个文本行的方向。一个缓解手段是在特征金字塔融合时再往上采样一层或者在3x3卷积后加一个空间注意力模块。如果不想改网络后处理时的行合并策略也值得花时间调把局部感知NMS中按行合并的IoU阈值从0.7放宽到0.5断开的框有更大几率被重新接上但代价是有些密度大的场景会把不同行并在一起。这个阈值值得多试几组找到符合你场景的最优值。5. EAST的局限性、衍生工作与现实选型建议5.1 EAST难以处理的四种极端输入虽然说EAST在当年是标杆级别的算法但它有四个明显的短板用在实际项目中必须心里有数。弯曲文本是EAST完全搞不定的。不管是拱形门牌号还是矿泉水瓶身上的环绕文字任何非线性的文本布局四边形表示法都无法描述。EAST给出的几何输出只能是矩形或任意四边形弯曲文本在score map上虽然也可能有大面积的响应但最终的geometry回归结果几乎必然是错的。极端长宽比的文本行也对EAST不友好。上面提过跨度很长的文本行会因为感受野不足发生断裂甚至某些情况下预测出的角度是整个文本行的平均方向但两个端点的偏移较大框无法贴合首尾文字。第二点是文本线虫问题。当一个文本行很短但旋转角度很大时RBOX的短边可能只有几个像素几个像素的框在特征图上几乎无法获得足够的空间信息。这种情况下EAST经常给出一个覆盖了整行但过度扩张的框导致与相邻文本框大面积重叠。最后是背景相似性的干扰这个更多是数据问题。如果场景里的窗户栅栏、铁轨、砖墙纹理和文字有类似的边缘响应score map上会出现大片的假阳性区域。EAST的几何回归对这种假阳性没有惩罚机制后处理阶段必须依赖最终的text score阈值过滤。但阈值调高了会漏掉真文本调低了会有大量假框。实际生产中往往需要再叠加一个轻量级的text/non-text分类器来做二次过滤。5.2 EAST在OCR生产链路中的位置与衍生改进尽管有上述短板EAST在OCR工程里的地位非常稳固因为它足够快、足够简单。在生产级OCR系统里文本检测与识别通常是两个独立模块检测模块负责框出文本区域识别模块负责把框里的文字翻译成字符串。EAST作为检测模块的优势在于推理速度快CPU上跑一张720p的图大约100毫秒以内GPU上不到30毫秒输出的是带角度的旋转框可以直接把框旋转成水平矩形再交给识别网络避免文本倾斜导致识别率急剧下降工程实现简单不需要像基于分割的算法那样搞复杂的可微分二值化等模块全流程都是一个标准卷积网络加少量后处理。后续很多算法其实都在EAST框架上做改进比如TextSnake用有序点序列来建模弯曲文本DBNet把概率图转二值图的过程变成可微分的从而在保持速度的同时大幅提升检测精度。如果你现在要选一个算法来落地DBNet在大多数场景下确实要比EAST强一截尤其在弯曲文本和密集文本上EAST的定位是“简单快速可解释”在计算资源有限、场景相对可控的项目里反而是更稳妥的选择。5.3 从EAST到DBNet的选型建议这里说说我的真实感受如果你是为了做项目而不是刷论文先别急着上最新的方案按这个思路选型基本不会有大问题场景里文字基本水平、文本行间距正常、拍摄角度稳定EAST足够甚至可以用更小的骨干网络换速度场景里文本行有各种旋转角度、但都是刚体旋转矩形区域内的旋转EAST加足够的旋转数据增强就能搞定场景里有弯曲文本弧形、环绕形或者文本行非常密集放弃EAST直接用DBNet或者PAN场景里有极端长文本超过图像宽度一半EAST表现不佳优先考虑分割类算法它们对长文本的连续性建模更友好。如果你手头只有CPU推理环境EAST的MobileNet变体几乎是最优解。ICDAR2015上效果最好的MobileNet版EAST能达到70%以上的F-score帧率在CPU上也能保持实时。这个性能在现代边缘设备上依然很有竞争力。5.4 性能实测数据不同主干网络与输入分辨率对比我把自己实验室里的一组对比测试数据放出来供大家选型参考。测试集是自家标注的300张停车场车牌和收费单据混合图单张分辨率约1280x720主干网络输入尺寸平均推理耗时(GPU)F-score备注VGG16512x51262ms0.79精度高但太慢ResNet50512x51245ms0.81综合表现最好ResNet50320x32022ms0.75降低分辨率可提速MobileNetV3512x51218ms0.72移动端推荐方案PVANet(原论文)720p约25ms0.78复现难度偏高从数据能看出ResNet50加512输入是精度和速度的甜点。MobileNetV3虽然精度下降了9个百分点但在边缘设备上的实用价值远高于那点精度优势。另外我建议如果你用GPU部署直接用FP16推理精度几乎无损速度能再提升30%到50%。5.5 轻量化方案在CPU上的部署经验部署轻量模型到CPU时有几个容易被忽略的工程细节。PyTorch模型先转ONNX再用OpenVINO或者ONNX Runtime做推理这是目前最成熟的CPU部署路线。转ONNX时需要注意两点一是输入输出的动态维度要设置好建议固定输入尺寸否则内存分配和算子优化都会受影响二是模型里的resize操作上采样在转ONNX时偶尔会算子兼容问题PyTorch的F.interpolate转出来的ONNX在不同推理引擎上行为可能有细微差异建议转换后在测试集上对比输出一致性。如果是ARM平台尤其是一些国产边缘盒子先用量化感知训练把模型权重量化到INT8再部署。EAST对这种低比特量化相对友好score map的精度受量化影响小geometry的连续回归值会有一点偏移但后处理阶段还会做NMS和阈值筛选这个偏移通常不会引起质变。实测在RK3588上MobileNetV3的INT8模型推理延迟可以压到15毫秒以内完全满足实时需求。最后强调一点EAST这类直接回归文本框的算法在搬到真实场景时后处理逻辑对最终效果的影响甚至超过网络本身。score map阈值、NMS的IoU阈值、行合并策略这三个参数的组合在不同场景下最优值差异很大一定要在自己数据的验证集上做网格搜索不要照搬论文。我把这个后处理搜索过程写成了一个简单的配置化模块不同场景切换参数只需要改配置文件不再需要重新训练。这也是我最推荐的做法模型权重不变靠调后处理参数适配不同业务场景省时省力。
返回列表