经过之前的迁移训练,其实在某些方面会比通用的模型要好一些,但是直接投入实际生产使用还是差一些,所以这里读一下paddleocr的源代码去了解一下现有的预处理和后处理情况。

1. 预处理

预处理也分为cls分类db检测east检测rec识别这几种情况,没有在FAQ文件中搜到统一的文件夹,自己去手动找找。根据PaddleOCR 的整体目录结构-tree结构可知,与预处理相关的内容

  • \PaddleOCR\tools
  • paddle PaddleSeg图像分割训练 paddleocr教程_顺时针

  • 读了一下源码,其中,
    predict_cls.py文件中只有一个类class TextClassifier(object),其中有两个比较重要的函数
    1. resize_norm_img(self, img) ,对图像做padding/缩放,对小的图片就做padding,对大的图片就缩小,将所有输入的batch的图像控制在一个相似的范围
    2. __call__()函数,返回img_list(图片列表), cls_res(分类结果,包括标签和得分), elapse(耗时,时间流逝 elapse += time.time() - starttime

predict_det.py文件

paddle PaddleSeg图像分割训练 paddleocr教程_预处理_02

可以看到,其实就是一个类,其中有6个函数,order_points_clockwise函数(按照顺时针对点排序),其实也都是一些关于检测的控制函数。


predict_rec.py文件,也主要是确定不同种类的解码方式涉及的字符集,重新变换图像的尺寸。不涉及什么传统CV领域的模糊,腐蚀,膨胀,边缘提取等操作。


  • 另外,还有PaddleOCR\deploy\cpp_infer\include\preprocess_op.h,不过这里的预处理也是很基础的。与这个文件配套的还有对应的.cpp文件,这里的预处理和后处理都属于部署之后的(推理时使用的预处理和后处理)
  • paddle PaddleSeg图像分割训练 paddleocr教程_浮点数_03

  • 不过这里的预处理和日常所想象的预处理,不太一样——这里的预处理,主要是来自配置文件,与我以为的图片送入模型之前的一些预处理方式不太一样。

PaddleOCR的deploy文件夹中的预处理主要包括以下内容(为了加速,都是C++语言写的):

  1. void Permute::Run(重新排列),这个函数的功能是将输入图片的像素点(主要是channel)进行重排,使之符合opencv的格式。

双冒号是域操作符,参考:c语言的双冒号是什么意思::

  1. void Normalize::Run(归一化),将像素点除以255,再进行归一化,缩小数值,控制在同一个量级。
  2. void ResizeImgType0::Run,当图像的长度或者宽度超过了max_size_len,就要对图形进行的尺寸进行重新缩放
  3. void CrnnResizeImg::Run
  4. void ClsResizeImg::Run

2. 后处理

根据模型的解码部分有后处理?

有的检测的后处理在ppocr/postprocess路径下

查看这个文件夹可以看到,主要就是cls分类db检测east检测rec识别这几种情况的后处理

paddle PaddleSeg图像分割训练 paddleocr教程_顺时针_04


其中,

  • cls分类的后处理文件中只有一个类:class ClsPostProcess(object),作用是:文本标签和文本索引之间的转换。
  • db检测的后处理文件也是一个类,class DBPostProcess(object),类中有几个函数:
  • boxes_from_bitmap()从二值化图像中获取boxes,返回标记框的坐标和得分;
  • unclip(),控制标记框与文字之间的距离,这个函数返回一个扩展因子(boxes要扩大的数量)
  • get_mini_boxes()返回最小的boxes
  • box_score_fast 返回boxes的score
  • _call_()函数 返回所有的boxes列表
  • rec识别的后处理文件就比较多,有四个类,
  • class BaseRecLabelDecode(object),这个类主要就是判断字符集,规定了支持的字符集(中文/英文等),特殊字符,文本序号和文本索引的转换
  • class CTCLabelDecode(BaseRecLabelDecode),和上面的基类差不多,都是涉及文本解码,将文本序号和文本索引转换,确定字符集/特殊字符/忽略字符等,其余下面两个类似。
  • class AttnLabelDecode(BaseRecLabelDecode)
  • class SRNLabelDecode(BaseRecLabelDecode),

其实上面的db检测的后处理措施和部署中使用c++写的后处理方式差不多。

部署的后处理

文件位于PaddleOCR\deploy\cpp_infer\src\postprocess_op.cpp这个文件夹中,主要包含以下函数:

  1. void PostProcessor::GetContourArea获取轮廓区域
  2. cv::RotatedRect PostProcessor::UnClip
  3. float **PostProcessor::Mat2Vec,将图像的矩阵转换为float类型的array数组返回
  4. std::vector<std::vector<int>>PostProcessor::OrderPointsClockwise 对点进行顺时针方向的排序(从左到右,从上到下) (order points clockwise[顺时针方向])
  5. std::vector<std::vector<float>> PostProcessor::Mat2Vector 将图像的矩阵转换为float类型的vector数组返回
  6. bool PostProcessor::XsortFp32(std::vector<float> a, std::vector<float> b) 判断元素为浮点数float的vector的精度,如果a中元素的精度不等于b中元素的精度,则返回false
  7. bool PostProcessor::XsortInt(std::vector<int> a, std::vector<int> b)和上面的很像,只是浮点数变成了整数
  8. std::vector<std::vector<float>> PostProcessor::GetMiniBoxes没看懂这个函数,就知道作用是返回最小的boxs
  9. float PostProcessor::BoxScoreFast(std::vector<std::vector<float>> box_array,cv::Mat pred) 返回score
  10. std::vector<std::vector<std::vector<int>>> PostProcessor::BoxesFromBitmap(const cv::Mat pred, const cv::Mat bitmap, const float &box_thresh, const float &det_db_unclip_ratio)这个应该是DB(差分二值化)相关的内容,涉及到box_thresh(低于这个阈值的boxs不予显示)和det_db_unclip_ratio(文本框扩张的系数,关系到文本框的大小)
  11. std::vector<std::vector<std::vector<int>>> PostProcessor::FilterTagDetRes(std::vector<std::vector<std::vector<int>>> boxes, float ratio_h, float ratio_w, cv::Mat srcimg)