Skip to main content

如何实现一个扫描全能王?

David LiuAbout 4 min

如何实现一个扫描全能王?

相信大家都有使用过扫描全能王吧,大家有没有考虑过如何实现一个扫描全能王呢?

我们将从如下五个方面,解决这个问题。

首先我们先对问题所需的任务进行一个分析

问题概览

三个需求

  • 找到图片中的纸张:边缘检测
  • 将纸张修复展平并放在图像中间:透视变换
  • 更进一步:如何识别图中文字?

文档扫描过程

扫描过程中,主要涉及到如上三个步骤:

123

  1. 边缘检测

    Canny算法,进行边界检测(结合高斯滤波函数)

    在课程中,我们也了解过卷积运算可以进行一些边缘的检测和过滤,这里的Canny算法也是利用用高斯一阶偏导核卷积图像、结合梯度和滤波函数进行边缘检测的。

    检测器算法的四个步骤:

    1. 用高斯一阶偏导核卷积图像
    2. 计算每个点的梯度幅值和方向
    3. 非极大值抑制
    4. 连接与阈值(滞后)

    (当然,感兴趣的同学,也可以尝试使用Meta开源的Segment Anything模型去做分割,这里就不再赘述)

  2. 获取纸张轮廓

    对检测到的边界求解一个近似轮廓

    findContours方法,找到上一步中的所有边缘。

    由于噪声点或图像清晰度的原因,我们Canny算法探测出来的边缘可能是一个很复杂的多边形,那么我们可以道格拉斯-普克算法(Douglas-Peucker),approxPolyDP方法求解近似多边形。我们找到最大的近似四边形作为我们的纸张。

  3. 透视变换

    我们再利用矩阵,进行坐标变换,将四边形展平放大。warpPerspective

OCR

  • CTPN 算法:检测文本位置
  • CRNN 算法:识别文本内容

CTPN 算法

ECCV 2016提出的一种文字检测算法

Z. Tian, W. Huang, T. He, P. He and Y. Qiao: Detecting Text in Natural Image with Connectionist Text Proposal Network, ECCV, 2016.

RPN(Region Proposal Network)方法(faster-rcnn)

文本通常都是从左往右写的(水平),并且字之间的宽度都大致相同固定宽度,来检测文本高度即可,但是如何应对变长序列呢?

本质上还是 RPN 方法(可参考 faster rcnn),可将检测到的框拼在一起。

  1. 使用 VGG16 的卷积阶段的网络层作为骨干网络,然后将图片输入 VGG16 网络中进行特征提取,生成特征图

  2. 在 ① 中输出的特征图中滑动进行 3*3 卷积,然后进行 im2col 操作,然后每次滑动都得到一个 3*3 通道数的特征向量,最后生成一个新的特征图,然后输入 BiLSTM 中进行序列特征提取,再传入全连接层中进一步提取特征

  3. 在 ② 的全连接层后接 3 个全连接层分支,分别预测垂直坐标回归、分类得分、水平平移量回归

  4. 将 ③ 中的预测垂直坐标回归和分类得分结果输入 RPN 中

网络架构

VGG 提取特征,BiLSTM 融入上下文信息,基于 RPN 完成检测

二分类:文字/背景

VGG 网络的 4 次池化,后面不进行了

没用 resnet(因为这个工作相对不新,用的传统方法)

任务

输出结果包括了三部分:2K 得分,2K 回归,1K 边界调整(相比于以前工作多的一部分,提升 2%)

边界调整能使得文本检测框效果更好,下列是调整后的结果:

合并小框

检测到每一个小块文本区域还需拼接成完整的文本区域:文本线构造方法

规则,分前向和后向两部分:

  • 先前向走,对于 Xi,基于重合度(0.7)与位置距离(50 像素)找到 score 值最大的的 X
  • 接下来再返向走(规则不变),比较两次得分值大小来判断序列。

CRNN 算法

CNN + RNN

卷积和递归神经网络结合在一起:由图像得到文本

每个词都需要上下文信息,所以只用 CNN 是不合适的

首先 CNN 进行特征提取,接下来 RNN 进行序列特征提取,最后得出预测结果即可。

CTC 模块

对齐,对于不同长度、间隔,但是语意一样的问题,如何处理

以前的方法:都识别,然后去重,重复的只留一个

CTC:预测特殊字符,(空的或者延续长的音就变成特殊字符),然后识别的时候过滤掉。

卷积、池化(保持宽度不变长度减半)

文本生成器

训练

数据集

数据获取

训练资源

AutoDL

12:14

15:38