2021SC@SDUSC
在前几篇博客中我学习并介绍了PaddleOCR的方向分类器中用到的模型和算法,今天的这篇博客就来学习一下方向分类器真正的作用和算法实现框架。
图片经过文字检测之后将图片中可能为文字的部分用矩形框标出,此时的文字可能是倒转的,然后由方向分类器处理矩形框,将角度不正确的文字处理成正常方向的。经过方向分类器处理后的文字矩形框再通过文字识别,提取其中的文字。由此看来,方向分类器是文字检测和文字识别之间不可或缺的一部分,只有正确方向的矩形框才可以被识别出来文字。
文字角度分类主要用于图片非0度的场景下,在这种场景下需要对图片里检测到的文本行进行一个转正的操作。在PaddleOCR系统内, 文字检测之后得到的文本行图片经过仿射变换之后送入识别模型,此时只需要对文字进行一个0和180度的角度分类,因此PaddleOCR内置的 文字角度分类器只支持了0和180度的分类。如果想支持更多角度,可以自己修改算法进行支持。
0和180度数据样本例子:
PaddleOCR中关于方向分类器的程序目录结构:
PaddleOCR
├── configs // 配置文件,可通过 yml 文件选择模型结构并修改超参
│ ├── cls // 方向分类器相关配置文件
│ │ ├── cls_mv3.yml // 训练配置相关,包括骨干网络、head、loss、优化器和数据
│ └── ...
│ ...
├── deploy // 部署相关
│ ├── android_demo // android_demo
│ │ ...
│ ├── cpp_infer // C++ infer
│ │ ├── CMakeLists.txt // Cmake 文件
│ │ ├── docs // 说明文档
│ │ │ └── windows_vs2019_build.md
│ │ ├── include // 头文件
│ │ │ ├── clipper.h // clipper 库
│ │ │ ├── config.h // 预测配置
│ │ │ ├── ocr_cls.h // 方向分类器
│ │ │ └── ...
│ │ ├── readme.md // 说明文档
│ │ ├── ...
│ │ ├── src // 源文件
│ │ │ ├── clipper.cpp
│ │ │ ├── config.cpp
│ │ │ ├── main.cpp
│ │ │ ├── ocr_cls.cpp
│ │ │ └── ...
│ │ └── tools // 编译、执行脚本
│ │ ├── build.sh // 编译脚本
│ │ ├── config.txt // 配置文件
│ │ └── run.sh // 测试启动脚本
│ ├── docker
│ │ └── hubserving
│ │ ├── cpu
│ │ │ └── Dockerfile
│ │ ├── gpu
│ │ │ └── Dockerfile
│ │ ├── README_cn.md
│ │ ├── README.md
│ │ └── sample_request.txt
│ ├── hubserving // hubserving
│ │ ├── ocr_cls // 方向分类器
│ │ │ ├── config.json // serving 配置
│ │ │ ├── __init__.py
│ │ │ ├── module.py // 预测模型
│ │ │ └── params.py // 预测参数
│ │ │ ...
│ │ └── ocr_system // 系统预测
│ │ ├── config.json
│ │ ├── __init__.py
│ │ ├── module.py
│ │ └── params.py
│ ├── imgs // 预测图片
│ │ ├── cpp_infer_pred_12.png
│ │ └── demo.png
│ ├── ios_demo // ios demo
│ │ ...
│ ├── lite // lite 部署
│ │ ├── cls_process.cc // 方向分类器数据处理
│ │ ├── cls_process.h
│ │ ├── config.txt // 检测配置参数
│ │ ├── crnn_process.cc // crnn 数据处理
│ │ ├── crnn_process.h
│ │ ├── db_post_process.cc // db 数据处理
│ │ ├── db_post_process.h
│ │ ├── Makefile // 编译文件
│ │ ├── ocr_db_crnn.cc // 串联预测
│ │ ├── prepare.sh // 数据准备
│ │ ├── readme.md // 说明文档
│ │ ...
│ └── slim
│ └── quantization // 量化相关
│ ├── export_model.py // 导出模型
│ ├── quant.py // 量化
│ └── README.md // 说明文档
├── doc // 文档教程
│ ...
├── ppocr // 网络核心代码
│ ├── data // 数据处理
│ │ ├── imaug // 图片和 label 处理代码
│ │ │ ├── text_image_aug // 文本识别的 tia 数据扩充
│ │ │ │ ├── __init__.py
│ │ │ │ ├── augment.py // tia_distort,tia_stretch 和 tia_perspective 的代码
│ │ │ │ ├── warp_mls.py
│ │ │ ├── __init__.py
│ │ │ ├── east_process.py // EAST 算法的数据处理步骤
│ │ │ ├── make_border_map.py // 生成边界图
│ │ │ ├── make_shrink_map.py // 生成收缩图
│ │ │ ├── operators.py // 图像基本操作,如读取和归一化
│ │ │ ├── randaugment.py // 随机数据增广操作
│ │ │ ├── random_crop_data.py // 随机裁剪
│ │ │ ├── rec_img_aug.py // 文本识别的数据扩充
│ │ │ └── sast_process.py // SAST 算法的数据处理步骤
│ │ ├── __init__.py // 构造 dataloader 相关代码
│ │ ├── lmdb_dataset.py // 读取lmdb数据集的 dataset
│ │ ├── simple_dataset.py // 读取文本格式存储数据集的 dataset
│ ├── losses // 损失函数
│ │ ├── __init__.py // 构造 loss 相关代码
│ │ ├── cls_loss.py // 方向分类器 loss
│ ├── metrics // 评估指标
│ │ ├── __init__.py // 构造 metric 相关代码
│ │ ├── cls_metric.py // 方向分类器 metric
│ ├── modeling // 组网相关
│ │ ├── architectures // 网络
│ │ │ ├── __init__.py // 构造 model 相关代码
│ │ │ ├── base_model.py // 组网代码
│ │ ├── backbones // 骨干网络
│ │ │ ├── __init__.py // 构造 backbone 相关代码
│ │ │ ├── det_mobilenet_v3.py // 检测 mobilenet_v3
│ │ │ └── ...
│ │ ├── necks // 颈函数
│ │ │ ├──...
│ │ ├── heads // 头函数
│ │ │ ├── __init__.py // 构造 head 相关代码
│ │ │ ├── cls_head.py // 方向分类器 分类头
│ │ │ ├── ...
│ │ ├── transforms // 图像变换
│ │ │ ├── __init__.py // 构造 transform 相关代码
│ │ │ └── tps.py // TPS 变换
│ ├── optimizer // 优化器
│ │ ├── __init__.py // 构造 optimizer 相关代码
│ │ └── learning_rate.py // 学习率衰减
│ │ └── optimizer.py // 优化器
│ │ └── regularizer.py // 网络正则化
│ ├── postprocess // 后处理
│ │ ├── cls_postprocess.py // 方向分类器 后处理
│ │ ├── db_postprocess.py // DB 后处理
│ │ └── ....
│ └── utils // 工具
│ ├── dict // 小语种字典
│ ....
│ ├── ic15_dict.txt // 英文数字字典,区分大小写
│ ├── ppocr_keys_v1.txt // 中文字典,用于训练中文模型
│ ├── logging.py // logger
│ ├── save_load.py // 模型保存和加载函数
│ ├── stats.py // 统计
│ └── utility.py // 工具函数
├── tools
│ ├── eval.py // 评估函数
│ ├── export_model.py // 导出 inference 模型
│ ├── infer // 基于预测引擎预测
│ │ ├── predict_cls.py
│ │ └── ...
│ ├── infer_cls.py // 基于训练引擎 预测分类
│ ├── ...
│ ├── program.py // 整体流程
│ ├── test_hubserving.py
│ └── train.py // 启动训练
├── paddleocr.py
├── README_ch.md // 中文说明文档
├── README_en.md // 英文说明文档
├── README.md // 主页说明文档
├── requirements.txt // 安装依赖
├── setup.py // whl包打包脚本
├── train.sh // 启动训练脚本
重要的配置部分有配置文件(configs/cls/cls_mv3.yml),部署方向分类器(deploy/cpp_infer/include/ocr_cls.h,deploy/cpp_infer/src/ocr_cls.cpp),Hub Serving实现服务化部署(deploy/hubserving/ocr_cls),lite 部署(deploy/lite/cls_process.cc和cls_process.h),量化瘦身(deploy/slim/quantization)。网络核心代码中有随机数据增广操作(ppocr/data/imaug/randaugment.py ),损失函数(ppocr/losses/cls_loss.py),评估指标(ppocr/metrics/cls_metric.py),组网相关(检测 mobilenet_v3:ppocr/modeling/backbones/det_mobilenet_v3.py,方向分类器分类头:ppocr/modeling/heads/cls_head.py),后处理(ppocr/postprocess/cls_postprocess.py)。工具有基于预测引擎预测(tools/infer/predict_cls.py)和基于训练引擎预测分类(tools/infer_cls.py)。
我会在以后的博客中仔细学习方向分类器的核心代码实现。