【RK部署】RK3566部署PaddleOCRv2踩坑记录

项目需要在rk3566板子上,实时识别用户在白纸上用马克笔写的字/字符,或者打印到白纸的字/字符。由于之前在Nvidia的NX板上部署过TensorRT版的PaddleOCRv2,过程很顺利,以为部署到RK板也会很容易,没想到啊,前前后后搞了1周多,下面是我的踩过坑的记录。

paddle2onnx

安装好Paddle环境,以及paddle2onnx环境之后,从PaddleOCR官网2.4版本的readme中找到如下图所示的文本检测模型和文本识别模型,然后根据deploy/paddle2onnx/readme.md中的转模型命令将模型转为onnx。

paddle2onnx --model_dir=./det_ch_PP-OCRv2/ 
--model_filename=inference.pdmodel
--params_filename=inference.pdiparams 
--save_file=./det.onnx
--opset_version=11
--input_shape_dict="{'x': [-1, 3, -1, -1]}" 
--enable_onnx_checker=True

paddleocr模型
在这里我遇到了第一个坑,RK不支持动态输入,也就是说转模型命令中的输入维度需要写成固定某个值,比如[1, 3, 480, 640], 即 batchsize=1, channel=3, height=480, width=640。这一点对检测模型影响不大,但对识别模型影响很大,在PaddleOCR中,识别模型的输入是[-1, 3, 32, -1],即固定文本高度为32,但宽度不定,那是因为不同的待识别文本的宽高比差异可能会很大,如果强行将所有待识别文本resize到固定大小,比如(32,96),会使得某些文本被拉伸/压缩变形严重,导致识别效果很差。
在这里插入图片描述

我尝试了两种解决方案,识别效果差不多。第一种,固定一个很大的宽高比进行模型转换,但不是直接对待识别文本进行resize,而是对待识别文本进行边缘填充。第二种,固定好几个宽高比转换多个模型,根据待识别文本的宽高比,自适应选择与其最接近的模型做识别。

第一种方案优点是简单直接,缺点是耗时,尤其是对于宽高比很小的文本,非常的浪费。第二种方案优点是省时,缺点是要初始化好几个模型,比较占内存。在实施第二种方案的时候,我遇到了第二个坑,当识别模型的输入宽度设的太小时,pc连板推理会一直卡在rknn.init_runtime()不动,也不报错,经过测试,当识别模型输入的宽度>96(这个值可能还能更小一点,还没进一步做更细致的测试),都是可以正常转模型和推理的。
在这里插入图片描述

PC连板推理

有了onnx模型之后,接着就是将onnx模型转为rknn模型。需要在PC上安装RK板的rknn-toolkits2,参考里面example的模型转化代码,以及Rockchip_Quick_Start_RKNN_SDK_V1.3.0_CN.pdf 文档,即可完成模型转化和模型推理。

在这里我遇到了第三个坑,rknn.config()里mean_values, std_values需配合输入数据谨慎设置,起初我对这两个参数的理解是对模型的输入数据做前处理(均值和方差),而我最开始设的mean_values=[0, 0, 0], std_values=[1, 1, 1],这么设置相当于没有做均值和方差处理,之所以这么设置是因为我把输入数据的前处理已经做了,具体是从BGR转为RGB,再经过 0~255的uint8到0~1 float32,最后经过均值{0.485f, 0.456f, 0.406f}, 方差{1 / 0.229f, 1 / 0.224f, 1 / 0.225f}处理,才喂给模型去推理,所以不需要额外再做处理。然俄,奇怪的事情发生了,PC连板推理(python接口)的非量化fp16模型可以正常推理,但量化模型int8效果非常差,可以说和正常结果毫不相关,最奇怪的是我将非量化的fp16模型进行板端推理(C接口),推理结果也是错的,这说明同一个模型,在不同接口推理结果不一样。

由于我的fp16模型连板推理可以成功,所以我从来没有怀疑我的模型转换设置有问题,直到我找到了PaddleOCR在rv1104部署,对比之后发现他并没有单独对输入数据做前处理,而是直接将uint8图像作为输入,但转模型的参数设的是mean_values=[127, 127, 127], std_values=[127, 127, 127],于是我死马当活马医,去掉输入数据的前处理(仅仅保留resize和BGR2RGB),更改转模型参数,最终,居然可以了,无论是PC连板推理的fp16, int8模型,还是板端推理的fp16, int8模型,都可以正常推理。

为了找出这种奇怪现象的内在逻辑,在输入不做前处理的基础上,我测试了不同转模型参数,发现不同的mean_values, std_values对模型推理结果有影响,尤其是设为[0,0,0], [1,1,1]时,文本检测模型没有检到任何东西; 在输入做了前处理的基础上,只有设为[0,0,0], [1,1,1]附近才能有检测结果,否则检不到任何东西。

现在对这两个参数的理解是,不仅仅是对输入数据做前处理,还对模型量化后的模型参数有影响,最好是根据模型训练的均值方差(取值范围0~1)换算到0~255范围,作为转模型的参数设置,并且输入模型的数据不需要额外做前处理

板端C++推理

git clone rknpu2,参考doc里Rockchip_Quick_Start_RKNN_SDK_V1.3.0_CN.pdf文档,以及example里的ssd demo写PaddleOCR板端推理代码。

以上所有代码可参考我的github仓库:https://github.com/zwenyuan1/PaddleOCRv2_rk3566/tree/master

  • 4
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值