如何实现一个扫描全能王?
如何实现一个扫描全能王?
相信大家都有使用过扫描全能王吧,大家有没有考虑过如何实现一个扫描全能王呢?
我们将从如下五个方面,解决这个问题。
首先我们先对问题所需的任务进行一个分析
问题概览
三个需求
- 找到图片中的纸张:边缘检测
- 将纸张修复展平并放在图像中间:透视变换
- 更进一步:如何识别图中文字?
文档扫描过程
扫描过程中,主要涉及到如上三个步骤:
123
边缘检测
Canny算法,进行边界检测(结合高斯滤波函数)
在课程中,我们也了解过卷积运算可以进行一些边缘的检测和过滤,这里的Canny算法也是利用用高斯一阶偏导核卷积图像、结合梯度和滤波函数进行边缘检测的。
检测器算法的四个步骤:
- 用高斯一阶偏导核卷积图像
- 计算每个点的梯度幅值和方向
- 非极大值抑制
- 连接与阈值(滞后)
(当然,感兴趣的同学,也可以尝试使用Meta开源的Segment Anything模型去做分割,这里就不再赘述)
获取纸张轮廓
对检测到的边界求解一个近似轮廓
findContours方法,找到上一步中的所有边缘。
由于噪声点或图像清晰度的原因,我们Canny算法探测出来的边缘可能是一个很复杂的多边形,那么我们可以道格拉斯-普克算法(Douglas-Peucker),approxPolyDP方法求解近似多边形。我们找到最大的近似四边形作为我们的纸张。
透视变换
我们再利用矩阵,进行坐标变换,将四边形展平放大。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),可将检测到的框拼在一起。
使用 VGG16 的卷积阶段的网络层作为骨干网络,然后将图片输入 VGG16 网络中进行特征提取,生成特征图
在 ① 中输出的特征图中滑动进行 3*3 卷积,然后进行 im2col 操作,然后每次滑动都得到一个 3*3 通道数的特征向量,最后生成一个新的特征图,然后输入 BiLSTM 中进行序列特征提取,再传入全连接层中进一步提取特征
在 ② 的全连接层后接 3 个全连接层分支,分别预测垂直坐标回归、分类得分、水平平移量回归
将 ③ 中的预测垂直坐标回归和分类得分结果输入 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