多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

EAST算法详解:场景文本检测的端到端高效方案

EAST算法详解:场景文本检测的端到端高效方案 做OCR相关项目绕不开的一个算法就是EAST全称Efficient and Accuracy Scene Text最初由旷视科技在CVPR 2017上提出。这个算法的名字起得很直白追求的就是两件事检测效率高、检测结果准。它解决的是场景文本检测问题也就是在一张自然图像里把文字区域找出来——注意是“找出来”不是直接识别内容所以它通常工作在OCR流程的前半段扛的是定位这杆大旗。我最早接触EAST是在做一个证件识别项目当时用目标检测的思路试过好几个方案要么是在小文字上漏检严重要么是速度达不到实时要求。后来换成EAST才第一次体会到“端到端文本检测”到底是什么体验——不需要候选框不需要后处理里的分割步骤一张图进去直接输出旋转矩形的顶点坐标干净利落。这篇文章我想把EAST从原理到复现、从踩坑到优化的完整链路都拆开讲一遍适合正在做OCR、票据识别、文档数字化、车牌检测这类任务的开发者参考也适合刚入场景文本检测方向、想找一篇经典算法作为切入点的同学。1. EAST算法的核心思路拆解从FCN到四边形的直接回归1.1 场景文本检测到底难在哪很多人第一次接触场景文本检测时会觉得这不就是通用目标检测加一个文本类别吗真上手以后才发现完全不是一回事。场景文字有几个很特别的属性第一长宽比极端一行文字可能是1:3也可能是1:10甚至更长通用检测器里预设的锚框很难覆盖这种跨度第二文字方向不固定水平、倾斜、甚至竖直排列都有用水平框会把大量背景框进来精度直接被拉低第三密集场景下相邻文本挨得很近比如货架标签、广告牌上的多行文字很容易被合并或漏检。在EAST出现之前主流方案基本走的是候选框加分类的路子。先生成一大堆可能包含文字的候选区域再用分类器判断哪些是真文字最后做边框回归。这套逻辑在通用目标检测上很成熟但在文本这种极长宽比、多方向的场景下候选框的质量很难保证而且中间环节多、计算冗余大速度一直上不去。我印象很深的是当时用某个两阶段模型跑一页A4文档文字密集的区域推理一次要几百毫秒根本没法用在实时预览场景里。1.2 EAST的解题思路砍掉中间过程直接回归文本行EAST的命名里“Efficient”和“Accuracy”不是随便写的它的核心思想就是一句话用一个全卷积网络直接预测文本区域跳过候选框、跳过分类、跳过后处理里的分割步骤。整个网络从输入图像到输出文本检测结果是一条笔直的流水线中间没有分叉、没有参与决策的中间模块。具体来说EAST输入一张图输出两个东西每个像素位置属于文本区域的得分图以及这个像素对应的文本区域几何信息。几何信息有两种表达方式一种叫RBOX即旋转矩形包含4个通道的偏移量到矩形上、右、下、左四条边的距离和1个通道的旋转角度另一种叫QUAD即任意四边形包含8个通道的顶点坐标偏移。拿到之后再做一步阈值化和NMS文本行的外接框就出来了。这种设计的聪明之处在于它把“文本检测”从一个区域分类问题转化成了一个逐像素回归问题。每个像素都参与预测天然支持任意长宽比的文本旋转框或四边形直接建模方向不需要靠数据硬学全卷积结构输出的是密集预测计算效率也比候选框方案高得多。当时在ICDAR2015数据集上EAST的F-score能到80%以上在一张720p图上推理耗时不到0.2秒这个成绩在今天看来已经过时但在当时算是把“效率”和“精度”同时拉满的代表作。1.3 EAST的整体架构说明书EAST的网络结构可以拆成三块来看理解这三块也就理解了整个算法的主干。第一块是骨干特征提取网络原文用的是PVANet一个为效率设计的轻量级CNN。实际复现时用VGG16、ResNet50也完全可行我自己就用过ResNet50跑过效果差别不大只是参数量和速度略有不同。骨干网的职责是把原始图像逐步抽象成不同尺度的特征图低层特征保留细节、高层特征富含语义。第二块是特征融合层。作者借鉴了U-Net的跳跃连接思想从骨干网的不同stage取出特征图从顶层开始逐步上采样、与下一层特征拼接然后再过卷积。这样每个位置的特征既包含细节信息又有语义信息对检测小文字和大文字都有好处。这一步是EAST能同时兼顾多尺度文本的关键。第三块是输出层。融合后的特征图接一个卷积输出通道数根据几何格式决定RBOX输出6个通道QUAD输出9个通道再加上1个通道的文本得分图。最终的特征图分辨率是原图的1/4也就是说原图上4x4的区域对应一个预测像素这个设计在后处理时需要特别注意后面我会详细讲。2. 核心原理逐个击破特征融合、几何图、损失函数与NMS2.1 特征融合层用U-Net思想把多尺度特征串起来EAST的特征融合层是很多人容易忽略但实际非常关键的部分。骨干网不同层输出的特征图分辨率不同、语义层级也不同。低层特征分辨率高、细节信息丰富对定位文本边界有帮助高层特征感受野大、语义信息强对判断一个区域是不是文本有帮助。如果只用最后一层特征做预测小文本的细节基本就丢了如果只用低层特征语义又不够。EAST的处理方式是把最高层的特征图逐步上采样到与上一层相同分辨率做通道拼接再经过一个卷积和上采样继续与更浅层拼接重复三次最终融合了四个层级的特征得到尺度信息丰富的特征图。这个结构后来在很多文本检测算法里都能看到影子比如DBNet的FPN分支思路是一脉相承的。我在实际训练中有一个体会骨干网用VGG16时融合层输出的特征表达能力偏弱文字边缘预测容易发虚换成ResNet50后因为底层残差结构的特征更丰富边缘得分图明显干净很多。这个差异在小文字多的数据集上非常明显如果你的任务以长文本为主可能感知不强一旦涉及大量小号字体骨干网络的选型会直接影响上限。2.2 输出层与几何图RBOX和QUAD怎么选EAST的几何输出有两种格式选哪种取决于你的任务场景。RBOX是旋转矩形用一个中心点和四条边的距离加一个旋转角度来描述文本区域。它的优势是参数少、回归难度低、后处理简单位置信息足够表达绝大多数规则文本行。QUAD是任意四边形用四个顶点的坐标偏移来描述区域自由度更高能拟合不规则文本但回归难度也更大训练时需要更多数据支撑。从实际效果来看大多数应用场景用RBOX就够了。票据、文档、车牌、横幅标语这些文本基本都是规则的矩形块旋转角度最多是倾斜远没到需要任意四边形才能描述的程度。QUAD更适合弯曲文本、艺术字这类不规则场景但EAST对曲线文本的支持本身有限所以别指望把QUAD当成万能解药。我的建议是先做RBOX跑通流程如果你的数据里确实存在大量不规则文本再切换到QUAD。另外要注意输出特征图的通道数RBOX模式下是6通道分别是score文本得分、d_box4个边距、d_angle旋转角HBB模式下不需要角度只有5通道QUAD是9通道score加8个顶点坐标。写网络的时候别搞混不然训练时损失函数和标签都对应不上。2.3 损失函数设计与下采样带来的边长补偿问题EAST的损失函数分两部分分类损失用dice loss回归损失用IoU loss。dice loss在处理正负样本极不平衡的像素级分割任务时比交叉熵稳定得多文本区域在整张图里的占比通常很小如果直接用交叉熵网络会倾向于把所有像素都预测成背景。IoU loss对旋转矩形的回归很友好它直接优化检测框与真实框之间的重叠度比单纯的L1或L2损失更贴合最终评价指标。这里有一个非常关键的细节EAST输出的几何图分辨率是原图的1/4训练时标签也必须对应地缩放到1/4但真实文本框的边长也需要跟着缩放。问题是任意四边形缩放后并不一定能保持平行四边形的性质。我的处理方式是保留原始标注的四边形信息按1/4比例缩小坐标后在缩小的标签图上计算每个像素到四条边的距离和旋转角。这个过程中小于4像素的短边基本就消失了所以在训练时还需要一个边长补偿把标注框按比例放大1.25倍再计算偏移。作者在论文里也提到了这个细节不注意的话模型对细长文本的召回率会明显偏低。2.4 Locality-Aware NMSEAST提速的关键武器熟悉通用目标检测的同学对NMS都不陌生但EAST用的不是标准NMS而是一个叫Locality-Aware NMS简称LANMS的变体。文本检测的候选框数量远多于通用检测而且很多框之间距离很近、彼此重叠如果对全图所有框做标准NMS随着图片尺寸增大计算量会指数级上升。LANMS的思路是先做按行合并。因为文本行是水平排列的相邻的预测框在位置上天然连贯作者按列对几何框进行排序将重叠度高的框两两合并再对合并后的框执行标准NMS。这样做的效果是候选框数量在大规模减少后才进入昂贵的全局NMS阶段整体提速非常明显而且因为合并操作基于文本行方向不会破坏检测精度。我自己复现的时候踩过一个坑如果按行合并的阈值设得太低相邻两行文字容易被合并成一个大框导致误检。这个阈值跟你的数据分布关系很大极密文本场景要适当调高IoU阈值比如从默认的0.5调到0.7能显著减少框粘连。3. 复现EAST环境搭建、数据准备与训练推理全流程3.1 环境搭建与依赖选型EAST的开源实现不少最经典的是GitHub上的argman/EAST工程基于TensorFlow 1.x年代久远直接跑起来会遇到不少环境问题。我自己在复现时做了个取舍模型结构按论文原文复刻用PyTorch实现依赖版本如下组件版本/方案Python3.8PyTorch1.10OpenCV4.5CUDA11.x图像处理albumentations、shapely如果你只是想在已有工程上快速跑通流程也可以直接基于一些第三方复现的代码改但一定要确认两点一是特征融合层的通道数是否与原文一致二是损失函数是否包含边长补偿项。很多简化版把这两块砍了检测效果会打折。3.2 数据集准备ICDAR2015与标注格式处理训练EAST最常用的数据集是ICDAR2015它提供了基于单词级别的四边形标注格式为四个顶点的x、y坐标。这个数据集是比赛场景采集的包含大量街景、招牌、门店文字难度适中用来训练EAST效果比较直观。数据集准备好之后有一个预处理步骤必须做好把四边形标注转换成训练所需的score图和geo图。简单说就是遍历每个标注框在1/4尺寸的score图上把框内像素标为1框外标为0然后在框内计算每个像素到四条边的距离和旋转角。如果标注是任意四边形还需要先计算最小外接旋转矩形这个用OpenCV的minAreaRect就能实现。整个过程看起来简单但处理顺序错了会出现标注错位的问题一定要先在原图上算好外接矩形再映射到小尺寸图上。数据增强方面我建议至少包含随机旋转、随机缩放、随机裁剪和颜色抖动。场景文本的方向变化多旋转增强对模型的泛化帮助很大。裁剪时要注意别把文字截断得太碎建议裁剪后的区域至少保留80%的标注框面积。3.3 训练过程与关键参数训练EAST有几个参数直接影响最终效果我把自己常用的配置整理如下参数推荐值说明输入尺寸512x512过小会丢失小文字过大则显存压力大batch size8-16按显存调整至少8起步初始学习率1e-3Adam优化器配合warmup训练轮数50-100看数据集规模小数据集50轮足够得分图阈值0.9推理时太高丢召回太低增加误检一个容易被忽略的点是模型保存策略。我建议按F-score而不是loss来选最优模型因为loss低不代表检测效果差有时候过拟合会让loss继续下降但召回率已经崩了。每两个epoch在验证集上算一次指标保留F-score最高的权重这个习惯能帮你省下不少调参时间。3.4 推理流程与NMS实现细节推理阶段比较关键的是后处理那几步顺序错了结果千差万别。核心代码示意如下import cv2 import numpy as np def postprocess(score, geo, score_thresh0.9, nms_thresh0.2): # 1. 通过得分图筛选文本像素 height, width score.shape[:2] boxes [] for y in range(height): for x in range(width): if score[y, x] score_thresh: continue # 2. 从geo图取边距与角度构造旋转矩形 d_top, d_right, d_bottom, d_left geo[y, x, :4] angle geo[y, x, 4] rect ((x, y), (d_left d_right, d_top d_bottom), -angle * 180.0 / np.pi) box cv2.boxPoints(rect) boxes.append(box) # 3. Locality-Aware NMS 或标准NMS if boxes: boxes np.array(boxes) # 按行合并 NMS这里用OpenCV的NMSBoxes做简化示意 indices cv2.dnn.NMSBoxesRotated( [(b[0], b[1], b[2], b[3], b[4]) for b in boxes], [1.0] * len(boxes), score_thresh, nms_thresh ) boxes boxes[indices.flatten()] return boxes这段代码里最值得注意的就两点一是角度单位换算geo图里的角度是弧度OpenCV的RotatedRect用的是角度而且正负方向的定义不同写错了框就会转错方向二是边距和位置的关系geo图里存的边距是四边的绝对像素长度直接用就行不要在中间加额外缩放否则框会变大或变小。推理速度上如果觉得瓶颈在循环遍历像素可以把得分图先做一次阈值化的二值化再用findContours提取连通域只对连通域中心附近的像素构造框。我实测这个优化能让推理时间减少一半左右精度损失几乎可以忽略。4. EAST的适用边界与真实应用场景分析4.1 真正能打的地方文档扫描、票据识别与视频抽帧EAST最舒服的落地场景是规则文本为主、背景相对干净的任务。文档扫描就是典型例子白纸黑字文字行方向基本水平EAST能以极低的误检率把文本行完整框出来。我自己做过一个合同扫描的批量处理工具EAST定位文本行后接一个轻量OCR模型整页文字的识别准确率能到97%以上处理一张300dpi扫描件的时间在0.3秒左右。票据识别是另一个高价值场景。发票、回执单、运单这类票据的版式复杂但文本本身是规则的打印体EAST对这类文本的召回率很高。配合关键信息抽取可以直接从票据图像里定位“发票号码”“金额”“日期”等字段的位置再交给识别模型。相比纯目标检测方案EAST对倾斜拍摄的容忍度高很多因为旋转框能贴合实际文字方向裁出来的文字块不需要额外做矫正。视频抽帧场景也有很多人在用EAST。视频里的字幕、路牌、商品标签如果用水平检测框会引入大量背景干扰EAST的旋转框能紧贴文字区域后续识别模型的输入更干净。尤其是直播平台上做内容审核的场景EAST能快速定位画面中的文字区域节省大量计算资源。4.2 容易翻车的地方曲线文本、长文本与密集交错场景EAST不是万能的它的局限也很明显。首当其冲的是曲线文本。EAST用旋转矩形或四边形来描述文本区域本质上假设文本是近似线性的遇到弯曲的文字——比如产品包装上的弧形标语、海报上的艺术字——检测框会覆盖大量非文本区域或者干脆断裂成好几段。如果项目里必须处理曲线文本建议直接考虑DBNet或PSENet这类基于分割的算法而不是在EAST上硬调。超长文本也是个容易翻车的点。当一行文字横跨整个图片宽度时EAST的旋转框可能被拆成几个小块原因是文本得分图在长文本中间区域可能出现断裂NMS阶段无法把这些碎片拼回完整文本行。我的经验是如果一行文字超过图片宽度的60%考虑按比例切分图像输入最后再合并检测结果或者把训练数据的输入尺寸调大。密集交错场景——比如文献截图里的多栏文本、杂志页面上的混排文章——EAST的按行合并策略容易失效导致多个文本行合并成一个框或者同一个文本行被拆成多个框。这类任务如果数据量不大可以通过调NMS参数缓解但根本上还是要数据密集场景的训练样本足够多让网络学会区分贴近的文本行。5. 常见问题与排查技巧实录5.1 高频报错与解决速查表现象可能原因解决方案训练loss不下降学习率过大或过小先用1e-3跑50轮观察曲线检测框全都缩成小点训练时标签边长补偿缺失按论文在计算边距前将标注框放大1.25倍文字区域得分图全是0标签映射时坐标没有缩放到1/4检查score图生成代码中的坐标换算检测框方向明显偏转角度单位或符号处理错误检查geo图角度与OpenCV RotatedRect的对应关系密集文字框粘连NMS阈值太低将IoU阈值从0.2提高到0.5以上推理速度慢逐像素遍历造框太慢改用连通域提取后只对中心像素造框5.2 几个必须避开的坑第一个坑是训练和推理时的输入尺寸不一致。有人训练时用512x512推理时直接喂原图网络的感受野和输出分辨率全变了检测框位置全部偏移。推理时一定要先把图片缩放到训练时的尺寸检测完再把框映射回原图坐标而且缩放比例在x和y方向要保持一致否则框的位置会歪。第二个坑是标注框的坐标系统不统一。有的数据集给的是整数坐标有的是浮点数还有的是左上右下格式、中心宽高格式清洗的时候不统一后面处理就全是错位。我的习惯是进入训练流程前先把所有标注统一成四个顶点的绝对坐标格式并保存一份可视化校验图人眼检查无误再进训练。第三个坑是损失函数里IoU计算在角度差较大时不稳定。旋转矩形的IoU计算比水平矩形复杂得多如果旋转角预测偏差大IoU loss的梯度可能会异常导致训练震荡。我的做法是在前20轮暂时固定角度的损失权重等边距回归稳定后再恢复完整损失实测能有效减少早期训练的不稳定。第四个坑比较隐蔽也是我在多语言场景下发现的标点符号和特殊字符极容易被漏检。原因在于很多数据集的标注框把标点和文字放在一起但网络学习时对面积太小的区域响应弱。如果任务里有密集标点场景建议在数据增强时叠加一个随机腐蚀操作强制模型学会从小区域中提取特征。5.3 从EAST出发还能怎么延伸如果你已经熟悉了EAST往后续技术的迁移成本并不高。现在文本检测领域的默认选择更偏向DBNet或者PSENet但EAST的很多思想在它们身上都有体现图像分割式的文本区域预测、多尺度特征融合、后处理中的按行合并策略这些你从EAST里理解透了再去读新论文会轻松很多。另外EAST和OCR引擎的衔接也值得专门做一次调优。很多OCR框架里自带文本检测模块但换用EAST后识别阶段的输入质量会有提升空间。关键点是裁出来的文本图像不要直接送识别模型建议先做一次透视矫正把旋转框变换成水平矩形再裁剪。这一步能显著提升识别准确率尤其在拍摄倾斜严重的场景。我自己的体会是算法迭代快但经典思路的底层逻辑不会过时。EAST作为场景文本检测的经典之作真正值得学习的不是那套具体的网络结构而是它“直接回归、端到端输出、按行合并加速”这套解题思路。理解了这套思路后面无论换多少新算法你都能快速看清它到底改了哪一环、提升了什么、牺牲了什么。
返回列表