[Share Experiences] 20.6 deepin文字识别突然变得好用了?OCR升级的秘密在这里!
Tofloor
poster avatar
white777
deepin
OM
2022-06-02 00:31
Author

ocr升级900x383.jpg

前段时间,很多社区的小伙伴们是不是已经察觉到:≡;°д°) 啥情况?deepin文字识别突然变得好用了?不仅成为速度王者,识别准确率也非常感人!

那么今天的文章,将会为大家揭开deepin-OCR全方位升级背后的技术秘密,期待大家在帖子下进行交流和探讨~

前言

几个月前,Deepin OCR 正式发布,在当时解决了文字识别功能在Deepin上从无到有的问题。但是,在初步满足文字识别需求的同时,这套基于 Tesseract 模型方案中,实际上存在两个较为明显的弱项:第一,识别率不是很高,尤其是在复杂的图文背景中,中文识别时会夹杂有不应出现的空格;第二,识别速度比较慢,主要发生在长篇幅和大图的场景。

所以,在上一版本 Deepin OCR 发布的同时,调研新的 OCR 解决方案的替代任务已经在紧锣密鼓的安排着。经过反复调研、适配和验证,甚至需要考虑对全国产平台硬件架构的支持,我们最终选择了 PaddleOCR-NCNN 作为 Deepin OCR 的后端


功能体验

首先,本次的替换仅限于后端模型,对 Deepin OCR 的前端交互没有做任何改变,这也是为了保持用户使用方式的一致性。

模型替换后,根据我们对同一个测试对象的文字识别测试体验而言,速度提升了约5倍,准确率提升了,且能有效应对更多的复杂场景(比如:低对比度的图片、背景芜杂不规整的图片等)。

下面放一组较为极端的对比:

1.老模型识别效果.png

2.新模型识别效果.png

【图1:替换前(上)与替换后(下)的低对比度场景识别展示】

其次,新模型的 DEB 包与部署完成后的体积也有了明显的优化:

模型替换前:DEB 包超过 50 MB,部署完成后仅模型就占了 64 MB之多;

模型替换后:DEB 包仅有 18 MB,部署完成后的全部体量只有 30 MB左右。

简而言之,变小了,也变强了!tail


技术实现

2.1 Deepin OCR 结构

如前所述,本次 Deepin OCR 升级主要是将后端替换为了 PaddleOCR-NCNN。说到这,你可能会觉得摸不着头脑,但不要慌,听我慢慢道来。

首先,我们需要介绍一下 Deepin OCR 的结构:

3.DeepinOCR图.png

【图2:Deepin OCR 结构】

如图所示,它的前端部分非常简单,只有给应用程序提供使用的 DBus 接口和用来展示识别结果的图形界面。这一次我们暂时保持不变,仅修改负责文本识别的后端算法模块。接下来我们将深入后端算法模块,了解本次升级 Deepin OCR 到底是升级了什么。

2.2 PaddleOCR 简介

在这一部分,我们将介绍的是本次后端替换的深度学习项目 PaddleOCR,其核心算法正式名称是 PP-OCR,我们采用的是它的 v2 版本。

项目地址:https://github.com/PaddlePaddle/PaddleOCR

论文地址:https://arxiv.org/pdf/2109.03144.pdf

首先,我们需要弄明白 OCR 的基本工作流程:

  1. 文本检测,输出文本块的位置;
  2. 根据文本块的位置将图片裁切下来;
  3. 对每一张裁切下来的图片进行文字识别并输出识别结果。

4.OCR基本工作流程.png

【图3:OCR基本工作流程】

关于文本检测步骤,PP-OCR 采用了 DBNet(DB 意为 Differentiable Binarization,可微二值化)(论文地址:https://arxiv.org/pdf/1911.08947.pdf

简而言之,就是使用一个骨干网络(backbone)提取图片的基本特征,然后将各层网络提取的特征级联(cascade)起来生成最终的特征图,此时再使用生成的特征输出概率图和阈值图,最后将这两个图使用 DB 算法进行融合得到 DB 二值图,使用 DB 二值图即可生成可用的文本框。

在 PP-OCR 的轻量模型中,DB 算法的骨干网络采用的是 MobileNetV3 Large x0.5,这一选择将透过 MobileNetV3 的特性有效提高在 CPU 上的检测速度,同时网络在训练阶段的输入矩阵的规格是 1 * 3 * 960 * 960,基本可以满足常规图片的需要。

完成了文本检测任务并输出文本框后,就进入了文本识别步骤。这一步骤将会接收来自文本检测步骤传入的多个文本框,并分别对每一个文本框里的图片进行识别工作。其中,PP-OCR 的 v2 版本的文本识别算法采用了相对传统的基于循环神经网络 RNN(Recurrent Neural Network)的策略:

首先,使用骨干网络提取图片的基本特征,接着使用 RNN 的变种 LSTM(Long short-term memory,长短时记忆)算法对特征进行进一步处理,最后对处理完毕的特征矩阵执行 Softmax 计算以得到概率分布,并使用 CTC(Connectionist temporal classification,连接时序分类)算法对其进行解码输出最终的识别结果。

6.PP-OCR V2 文本识别流程.png

【图4:PP-OCRv2 文本识别流程】

在 PP-OCR 的轻量模型中,识别算法的骨干网络分为两种:

第一种:v2.0 版本,采用的是 MobileNetV3 Small x0.5,这个网络的特点是最终生成的模型文件小,且在 CPU 上非常快;

第二种:v2.1 版本,采用的是 MobileNetV1 Enhance,这个网络最终生成的模型文件稍大,识别速度稍慢,但精度更高,只是这个版本最终仅应用在了中英文模型上,其它的官方推理模型只有 v2.0 的结构。同时因为这是精度要求更高的识别任务,因此网络的输入矩阵的规格相对较小,是 1 * 3 * 32 * -1。

上面是关于主算法 PP-OCR,接下来将介绍我们相对于官方 demo 的改进点。

2.3 我们对于官方Demo的改进

在 PaddleOCR 官方的 C++ 部署 demo 中,仅在单次的文本识别中应用多线程计算,但实际上对于 LSTM 这类 RNN 网络来说,这样并不能有效提高整体的计算效率,因为 RNN 的计算流程如下:

7.RNN 网络计算流程.png

【图5:RNN 网络计算流程】

如图所示,RNN 是一种对多线程极不友好的算法:在 t-1 时刻的计算完成前,t 时刻的计算不会启动,而在 t 时刻的计算完成前,t+1 时刻的计算也不会启动,因此在单次的识别中,应当尽量使用少的线程进行。

因此我们在部署的时候相对于官方 demo 作出了改变:同时进行多个识别任务,而不是在单次识别中使用多线程,以此来尽可能提高识别过程的整体速度。

2.4 从 PaddlePaddle 到 NCNN

如果看了以上对于主算法的介绍还不过瘾,那么坐稳了,接下来将讲解我们是如何部署 PaddleOCR 的。

首先,要明确几个框架之间的关系:

众所周知,深度学习项目分为训练和部署两个大的阶段:

在训练阶段依赖一套以提供功能为目标的训练框架构建并训练模型,国外比较知名的训练框架有Tensorflow,Pytorch,MXNet,DarkNet,Caffe等,国产的训练框架主要有PaddlePaddle、MegEngine等;

而在部署阶段,则需要依赖一套以提供高性能为目标的推理框架来完成最终的落地任务,一般来说,训练框架都会自带一套推理框架,比如 PaddlePaddle 下的Paddle Inference,但一般训练框架自带的推理框架在体量和效率上都不尽人意,于是就涌现出了一批体量小还效率高的推理框架,国内比较常见的轻量推理框架有 NCNN、MNN、Paddle Lite 等,对于推理框架而言,中国是走在世界前列的。

本次技术升级中的主算法 PaddleOCR 的模型是由训练框架 PaddlePaddle 训练完成,官方也提供了基于Paddle Inference和Paddle Lite 的推理模型,我们最终使用工具将基于 Paddle Inference的模型转换到了 NCNN 下,并使用 NCNN 完成最终的部署。

为什么选择NCNN 进行部署呢?

它作为目前国内乃至世界领先的开源推理框架,我们相中的是它的几乎零成本的跨平台能力、高效的推理速度以及极小的部署体积等优点(项目地址:https://github.com/Tencent/ncnn)。

为什么不使用同样轻量的 Paddle Lite 呢?

原因在于:它在 x86 架构下强依赖 Intel 的 MKL 库,这是一个带有美国专利的闭源软件库,最终我们决定放弃它。

怎样从 PaddlePaddle 模型转换到 NCNN 模型?

PaddleOCR 作为 PaddlePaddle 下的子项目,官方仅提供了 PaddlePaddle 原始模型、Paddle Inference 模型,以及 Paddle Lite 模型。目前从 PaddlePaddle 到 NCNN 的转换存在两条路径:

PaddlePaddle -> Paddle Inference -> ONNX -> NCNN

PaddlePaddle -> Paddle Inference -> Pytorch -> TorchScript -> NCNN

第一条路径:PaddlePaddle 官方推荐的路径,使用由官方维护的 Paddle2ONNX 工具可以直接转换到 ONNX 模型,然后使用 ONNX 社区提供的 ONNX Simplifier 工具对输出模型的算子进行融合优化,最后再使用由 NCNN 社区维护的 ONNX2NCNN 工具将其转换到 NCNN 模型。

第二条路径:使用项目 https://github.com/frotms/PaddleOCR2Pytorch 提供的工具将 Paddle Inference 的模型转换到 Pytorch 的 pth 文件,然后使用 Pytorch 中的工具以 Trace 模式将 pth 文件转换到 TorchScript 格式,最后使用 NCNN 工具箱中的 PNNX 将其输出到 PNNX 和 NCNN 格式,取 NCNN 格式的模型文件进行部署即可。

本次我们使用的是第一条路径进行的转换。

以上内容介绍完了我们部署的主要流程,但除此之外,我们针对轻量化部署这一问题所做的不止使用 NCNN。

2.5 OpenCV 的裁剪

OpenCV 作为知名的图像处理库,它在 PaddleOCR 的算法流程中起到了重要的辅助作用。但是原始的 OpenCV 库体积实在是太大,直接搬过来用的话,社区的小伙伴们肯定不满意。我们经过调研找到了一个可以方便裁剪它的方案 OpenCV-Mobile(项目地址:https://github.com/nihui/opencv-mobile

这个项目利用禁用 RTTI、替换轻量图片读写库 stbimage、移除 zlib 组件、禁用几乎全部的编译选项等手段达到最大化缩减 OpenCV 主库体积的目的,同时在功能和性能上满足绝大部分深度学习项目。

2.6 隐私处理

经过以上的技术升级,我们的OCR软件在速度和准确率上都有一个大幅度的提升,但我们依然是离线识别方案,所有的识别工作依旧都会在本地完成,以此充分保证用户的数据和隐私安全。


结语

以上便是我们对 Deepin-OCR 的完整技术介绍,欢迎各位小伙伴们前去升级试用,有任何的疑问和建议,欢迎与我们一起探讨哟!

Deepin OCR 项目仓库地址:https://github.com/linuxdeepin/deepin-ocr

本次升级涉及到的开源项目汇总,排名不分先后,每一项都非常重要:

PaddleOCR:https://github.com/PaddlePaddle/PaddleOCR

Paddle2ONNX:https://github.com/PaddlePaddle/paddle2onnx

OpenCV:https://opencv.org/

OpenCV Mobile:https://github.com/nihui/opencv-mobile

NCNN:https://github.com/Tencent/ncnn

ONNX Simplifier:https://github.com/daquexian/onnx-simplifier

Clipper:http://angusj.com/delphi/clipper.php

在此向开源社区的各位表示十分的感谢!

Reply Favorite View the author
All Replies
1 / 2
To page
jjcui8595
Moderator
2022-06-02 00:39
#1

感谢技术人员的不懈努力

Reply View the author
lovejonny
deepin
2022-06-02 01:28
#2

能不能搞个win的萤石云,海康威视一款看监控的软件,很需要

Reply View the author
blue_whale
deepin
2022-06-02 01:28
#3

感谢技术人员的不懈努力agree

Reply View the author
wtz
deepin
2022-06-02 02:17
#4

applaud 期待深度学习深度融入深度操作系统!

Reply View the author
TSAC
deepin
2022-06-02 02:38
#5

看不太懂,但大受震撼

感谢技术人员的努力

Reply View the author
心平气和
deepin
2022-06-02 02:43
#6

百度的paddlepaddle还是很良心的

Reply View the author
Jokul
deepin
2022-06-02 03:48
#7

其实我到现在为止还不知道从哪里去使用OCR功能呢joy

Reply View the author
xuqi
deepin testing team
2022-06-02 03:55
#8

OCR的功能nice,很全啊,学习了~

Reply View the author
皇華
deepin
2022-06-02 03:56
#9

飛槳不錯。

下一步應支持縱排文字。

山海經箋疏-郝懿行,欒保羣-中華書局K928-2019(1).png

古樂苑.52卷.目錄2卷.前卷1卷.衍錄4卷.明.梅鼎祚辑.明萬曆19年吕胤昌校刊本.1591年(1).png

Reply View the author
zhangqf
deepin
2022-06-02 04:53
#10
Jokul

其实我到现在为止还不知道从哪里去使用OCR功能呢joy

Ctrl-Alt-A打开截图画面,鼠标选中需要识别的区域,然后点击上下文工具栏中的“[A]”按钮。

Reply View the author
7f
deepin
2022-06-02 04:57
#11

干货满满,没想到在deepin论坛上看深度学习😄

Reply View the author
蒙笛
deepin
2022-06-02 06:33
#12

这个厉害,实测效果确实好tail

Reply View the author
均分菌
deepin
2022-06-02 06:48
#13
皇華

飛槳不錯。

下一步應支持縱排文字。

山海經箋疏-郝懿行,欒保羣-中華書局K928-2019(1).png

古樂苑.52卷.目錄2卷.前卷1卷.衍錄4卷.明.梅鼎祚辑.明萬曆19年吕胤昌校刊本.1591年(1).png

我试了 deepin OCR可以识别竖排 但是总体编排是从左往右而不是从右往左

而且deepin OCR对繁体支持不佳

Reply View the author
就是好奇
deepin
2022-06-02 08:05
#14
皇華

飛槳不錯。

下一步應支持縱排文字。

山海經箋疏-郝懿行,欒保羣-中華書局K928-2019(1).png

古樂苑.52卷.目錄2卷.前卷1卷.衍錄4卷.明.梅鼎祚辑.明萬曆19年吕胤昌校刊本.1591年(1).png

别对深度ocr抱太高期望……

深度OCR的定位可能就没考虑这么多……

繁体竖排甚至写本、刻本识别,这种偏门且专精的需要,还是交给专业软件做吧。

繁体竖排的可以用abbyy。写本、刻本的识别,可以用中华书局最近推出的OCR服务。

Reply View the author
GBwater
deepin
2022-06-02 14:19
#15

深度ocr之前太不准了,我还自己装了个paddle。。。这下好了yeah

Reply View the author
sSs
deepin
2022-06-02 16:56
#16

系统语言不同识别效果Screenshot_deepin-ocr_20220602084725.png

Reply View the author
tmzqcn
deepin
2022-06-02 17:09
#17
皇華

飛槳不錯。

下一步應支持縱排文字。

山海經箋疏-郝懿行,欒保羣-中華書局K928-2019(1).png

古樂苑.52卷.目錄2卷.前卷1卷.衍錄4卷.明.梅鼎祚辑.明萬曆19年吕胤昌校刊本.1591年(1).png

抓到LaTeX大佬一只

joy

Reply View the author
andktan
deepin
2022-06-02 17:16
#18

like

Reply View the author
毛毛虫
deepin
2022-06-02 17:17
#19

can you help me English Environment identification Chinese Problem Solution?

AI不能识别中文.png

Reply View the author
bluesky_
deepin
2022-06-02 17:36
#20

考虑一下把人脸识别也换ncnn吧,ncnn识别率和速度和seetaface差不多,但是拥有更少的内存占用和空间占用

Reply View the author
1 / 2
To page