记录如何在RK3588板子上跑通paddle的OCR模型

paddle官方给出的如何基于rknpu2搭建环境

根据官方给的提示
1、在Windows系统下的Ubuntu系统中完成环境搭建

  • 安装模型转换环境
conda create -n rknn2 python=3.6
conda activate rknn2

如果没有conda使用如下指令,跟随屏幕上的指示完成安装过程

wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh
bash Miniconda3-latest-Linux-x86_64.sh
source ~/.bashrc
#检验安装成功
conda --version
#退出环境
conda deactivate
  • 安装Ubuntu依赖包
sudo apt-get install libxslt1-dev zlib1g zlib1g-dev libglib2.0-0 libsm6 libgl1-mesa-glx libprotobuf-dev gcc g++

安装RKNNtoolkit2

RKNNtoolkit2的作用是将onnx模型转为rknn模型

# rknn_toolkit2对numpy存在特定依赖,因此需要先安装numpy==1.16.6
pip install numpy==1.16.6

# 安装rknn_toolkit2-1.3.0_11912b58-cp38-cp38-linux_x86_64.whl
wget https://bj.bcebos.com/fastdeploy/third_libs/rknn_toolkit2-1.5.1b19+4c81851a-cp36-cp36m-linux_x86_64.whl
pip install rknn_toolkit2-1.5.1b19+4c81851a-cp36-cp36m-linux_x86_64.whl

安装paddle2onnx

这一步为下面模型转换做打算:
paddle2onnx的作用:
paddle模型------>onnx模型
RKNNtoolkit2的作用:
onnx模型------>rknn模型

安装paddle2onnx的过程极为简单,在终端输入:

pip install paddle2onnx

至此,ubuntu上面的环境已经搭建完毕。

2、在板子上完成环境搭建

  • FastDeploy库的编译(在rk3588板子上进行)

rk3588性能强劲,可以直接在板子上借助图形界面编译FastDeploy

使用git clone https://github.com/PaddlePaddle/FastDeploy.git指令拉取代码。
这里有个小建议,如果git clone的速度实在是太慢,而你又有clash等科学软件。这里有两个指令能帮到你提升速度:

git config --global http.proxy http://192.168.1.1:7890
git config --global https.proxy http://192.168.1.1:7890

其中,192.168.1.1为安装了clash的主机ip地址。7890为clash界面Port的值。需要打开Port下面的Allow LAN选项!!其他科学软件大同小异。

回到正题

拉去代码在本地后执行如下操作:

cd FastDeploy

# 如果您使用的是develop分支输入以下命令
git checkout develop

mkdir build && cd build
cmake ..  -DENABLE_ORT_BACKEND=OFF \
	      -DENABLE_RKNPU2_BACKEND=ON \
	      -DENABLE_VISION=ON \
	      -DRKNN2_TARGET_SOC=RK3588 \
          -DCMAKE_INSTALL_PREFIX=${PWD}/fastdeploy-0.0.0

# build if soc is RK3588
make -j8
# build if soc is RK356X
make -j4

make install

执行完毕后FastDeploy库就编译完成了。请留意现在的地址,后面编译ocr程序时会用上。

按照官方教程安装三个模型:
此处装模型操作均在Ubuntu系统上,注意不是在板子上!!!

#新建一个文件夹
mkdir ppocr
cd ppocr
# 下载PP-OCRv3文字检测模型
wget https://paddleocr.bj.bcebos.com/PP-OCRv3/chinese/ch_PP-OCRv3_det_infer.tar
tar -xvf ch_PP-OCRv3_det_infer.tar
# 下载文字方向分类器模型
wget https://paddleocr.bj.bcebos.com/dygraph_v2.0/ch/ch_ppocr_mobile_v2.0_cls_infer.tar
tar -xvf ch_ppocr_mobile_v2.0_cls_infer.tar
# 下载PP-OCRv3文字识别模型
wget https://paddleocr.bj.bcebos.com/PP-OCRv3/chinese/ch_PP-OCRv3_rec_infer.tar
tar -xvf ch_PP-OCRv3_rec_infer.tar

第一个det模型在图片中检测文字的存在
第二个cls模型确定文字的方向
第三个rec模型识别文字的内容

上面操作结束后会得到三个装有paddle模型的文件夹,随即进入paddle----onnx模型步骤

paddle2onnx --model_dir ch_PP-OCRv3_det_infer \
            --model_filename inference.pdmodel \
            --params_filename inference.pdiparams \
            --save_file ch_PP-OCRv3_det_infer/ch_PP-OCRv3_det_infer.onnx \
            --enable_dev_version True
paddle2onnx --model_dir ch_ppocr_mobile_v2.0_cls_infer \
            --model_filename inference.pdmodel \
            --params_filename inference.pdiparams \
            --save_file ch_ppocr_mobile_v2.0_cls_infer/ch_ppocr_mobile_v2.0_cls_infer.onnx \
            --enable_dev_version True
paddle2onnx --model_dir ch_PP-OCRv3_rec_infer \
            --model_filename inference.pdmodel \
            --params_filename inference.pdiparams \
            --save_file ch_PP-OCRv3_rec_infer/ch_PP-OCRv3_rec_infer.onnx \
            --enable_dev_version True

大家应该都能看懂这里的参数

然后固定onnx模型的形状:
这里需要注意的是,根据ubuntu系统上python版本的不同,python指令可能会替换为python3

# 固定模型的输入shape
python -m paddle2onnx.optimize --input_model ch_PP-OCRv3_det_infer/ch_PP-OCRv3_det_infer.onnx \
                               --output_model ch_PP-OCRv3_det_infer/ch_PP-OCRv3_det_infer.onnx \
                               --input_shape_dict "{'x':[1,3,960,960]}"

python -m paddle2onnx.optimize --input_model ch_ppocr_mobile_v2.0_cls_infer/ch_ppocr_mobile_v2.0_cls_infer.onnx \
                               --output_model ch_ppocr_mobile_v2.0_cls_infer/ch_ppocr_mobile_v2.0_cls_infer.onnx \
                               --input_shape_dict "{'x':[1,3,48,192]}"

python -m paddle2onnx.optimize --input_model ch_PP-OCRv3_rec_infer/ch_PP-OCRv3_rec_infer.onnx \
                               --output_model ch_PP-OCRv3_rec_infer/ch_PP-OCRv3_rec_infer.onnx \
                               --input_shape_dict "{'x':[1,3,48,320]}"

python3指令:

python3 -m paddle2onnx.optimize --input_model ch_ppocr_mobile_v2.0_cls_infer/ch_ppocr_mobile_v2.0_cls_infer.onnx \
                               --output_model ch_ppocr_mobile_v2.0_cls_infer/ch_ppocr_mobile_v2.0_cls_infer.onnx \
                               --input_shape_dict "{'x':[1,3,48,192]}"

python3 -m paddle2onnx.optimize --input_model ch_PP-OCRv3_rec_infer/ch_PP-OCRv3_rec_infer.onnx \
                               --output_model ch_PP-OCRv3_rec_infer/ch_PP-OCRv3_rec_infer.onnx \
                               --input_shape_dict "{'x':[1,3,48,320]}"

python3 -m paddle2onnx.optimize --input_model ch_PP-OCRv3_det_infer/ch_PP-OCRv3_det_infer.onnx \
                               --output_model ch_PP-OCRv3_det_infer/ch_PP-OCRv3_det_infer.onnx \
                               --input_shape_dict "{'x':[1,3,960,960]}"
                      

至此执行完毕后,paddle模型转到onnx模型完毕,接下来是onnx模型转到rknn模型。

将这个rknpu2_tools文件夹的内容搬到ppocr文件夹下

随后输入以下三条指令:

python3 rknpu2_tools/export.py --config_path rknpu2_tools/config/ppocrv3_det.yaml --target_platform rk3588
python3 rknpu2_tools/export.py --config_path rknpu2_tools/config/ppocrv3_rec.yaml --target_platform rk3588
python3 rknpu2_tools/export.py --config_path rknpu2_tools/config/ppocrv3_cls.yaml --target_platform rk3588

当三条指令结束运行时,终端内容应该都是:

D RKNN: [03:17:31.652] ----------------------------------------
D RKNN: [03:17:31.652] <<<<<<<< end: N4rknn21RKNNMemStatisticsPassE
I rknn buiding done.
W init_runtime: Target is None, use simulator!
Export OK!

如果提示错误,说明你的rknn_toolkit2版本过时了,这时候要卸载旧的rknn_toolkit2

#先查看当前pip安装的rknntoolkit2版本:
pip list
#确实是否过时,如果过时就卸载:
pip uninstall rknn-toolkit2==1.4.0-22dcfef4

然后根据文档安装最新的rknntoolkit2:

git clone https://github.com/rockchip-linux/rknn-toolkit2.git

pip安装requirements
安装对应的wheels。。。
这些根据官方文档重新安装即可。

这时候在每个模型的解压文件夹下就得到了rknn模型。

ppocr/ch_ppocr_mobile_v2.0_cls_infer/ch_ppocr_mobile_v20_cls_infer_rk3588_unquantized.rknn
ppocr/ch_PP-OCRv3_det_infer/ch_PP-OCRv3_det_infer_rk3588_unquantized.rknn
ppocr/ch_PP-OCRv3_rec_infer/ch_PP-OCRv3_rec_infer_rk3588_unquantized.rknn

将这些文件拷贝到板子上:
首先进入板子上刚刚编译完毕的FastDeploy文件夹下的
/FastDeploy/examples/vision/ocr/PP-OCR/rockchip/cpp
创建一个新的文件夹build
回到cpp文件夹下,打开CMakeLists.txt,对include部分进行修改。以下是我修改好的代码:

PROJECT(infer_demo C CXX)
CMAKE_MINIMUM_REQUIRED (VERSION 3.10)

# 指定下载解压后的fastdeploy库路径
option(FASTDEPLOY_INSTALL_DIR "/home/blueberry/FastDeploy/build/fastdeploy-0.0.0")

# 需要修改的地方!!!
# 需要手动在FastDeploy的build,
# 也就是你进行编译FastDeploy时的那个文件夹下面找到FastDeploy.cmake这个文件!!!!!
include(/home/blueberry/FastDeploy/build/fastdeploy-0.0.0/FastDeploy.cmake)

# 添加FastDeploy依赖头文件
include_directories(${FASTDEPLOY_INCS})

add_executable(infer_demo ${PROJECT_SOURCE_DIR}/infer.cc)
# 添加FastDeploy库依赖
target_link_libraries(infer_demo ${FASTDEPLOY_LIBS})

cd到刚刚创建的FastDeploy/examples/vision/ocr/PP-OCR/rockchip/cpp/build文件夹下,进行如下操作:

# 使用编译完成的FastDeploy库编译infer_demo
cmake .. -DFASTDEPLOY_INSTALL_DIR=${PWD}/fastdeploy-rockchip
make -j

注意,此处编译完会生成一个叫infer_demo的程序,这个就是我们的ocr程序了。

如果cmake失败,这时需要对它依赖的库进行分析:

ldd infer_demo

我这里经过配置后能正常运行的结果:

	linux-vdso.so.1 (0x0000007f8b43a000)
	libfastdeploy.so.0.0.0 => /home/blueberry/FastDeploy/build/fastdeploy-0.0.0/lib/libfastdeploy.so.0.0.0 (0x0000007f8aad6000)
	libopencv_imgcodecs.so.3.4 => /home/blueberry/FastDeploy/build/third_libs/install/opencv/lib/libopencv_imgcodecs.so.3.4 (0x0000007f8a90e000)
	libopencv_core.so.3.4 => /home/blueberry/FastDeploy/build/third_libs/install/opencv/lib/libopencv_core.so.3.4 (0x0000007f8a601000)
	libstdc++.so.6 => /lib/aarch64-linux-gnu/libstdc++.so.6 (0x0000007f8a40c000)
	libgcc_s.so.1 => /lib/aarch64-linux-gnu/libgcc_s.so.1 (0x0000007f8a3e8000)
	libc.so.6 => /lib/aarch64-linux-gnu/libc.so.6 (0x0000007f8a273000)
	librknnrt.so => /lib/librknnrt.so (0x0000007f89d62000)
	libopencv_video.so.3.4 => /home/blueberry/FastDeploy/build/third_libs/install/opencv/lib/libopencv_video.so.3.4 (0x0000007f89d0f000)
	libopencv_calib3d.so.3.4 => /home/blueberry/FastDeploy/build/third_libs/install/opencv/lib/libopencv_calib3d.so.3.4 (0x0000007f89c04000)
	libopencv_imgproc.so.3.4 => /home/blueberry/FastDeploy/build/third_libs/install/opencv/lib/libopencv_imgproc.so.3.4 (0x0000007f89809000)
	libm.so.6 => /lib/aarch64-linux-gnu/libm.so.6 (0x0000007f8975e000)
	libpthread.so.0 => /lib/aarch64-linux-gnu/libpthread.so.0 (0x0000007f8972d000)
	libz.so.1 => /lib/aarch64-linux-gnu/libz.so.1 (0x0000007f89703000)
	libdl.so.2 => /lib/aarch64-linux-gnu/libdl.so.2 (0x0000007f896ef000)
	/lib/ld-linux-aarch64.so.1 (0x0000007f8b40a000)
	libopencv_flann.so.3.4 => /home/blueberry/FastDeploy/build/third_libs/install/opencv/lib/libopencv_flann.so.3.4 (0x0000007f8968b000)

如果有一些找不到的可以在系统中搜索名字,并手动指定目录
例如:我缺少的库都在/home/blueberry/FastDeploy/build/third_libs/install/opencv/lib下,我就在/FastDeploy/examples/vision/ocr/PP-OCR/rockchip/cpp/build下执行指令:

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/blueberry/FastDeploy/build/third_libs/install/opencv/lib

然后重新执行代码

# 使用编译完成的FastDeploy库编译infer_demo
cmake .. -DFASTDEPLOY_INSTALL_DIR=${PWD}/fastdeploy-rockchip
make -j

这里有个小提示:
官方要求rknn库的版本为1.4.2,我自己跑通用的是
瑞芯微官方rknpu2仓库下已经编译好的最新的rknn库,版本为1.5.2
1.4.0版本有问题,不知道是不是我人品的缘故。。。
直接将这个库扔到板子的/lib文件夹下面就好,替代原来版本。也可以在cmake的时候进行手动指定。

这时候就把之前在Ubuntu上转的rknn模型拷贝到板子上,然后下载图片和字典文件

# 下载图片和字典文件
wget https://gitee.com/paddlepaddle/PaddleOCR/raw/release/2.6/doc/imgs/12.jpg
wget https://gitee.com/paddlepaddle/PaddleOCR/raw/release/2.6/ppocr/utils/ppocr_keys_v1.txt

这时候就可以运行程序了:

./infer_demo ch_PP-OCRv3_det_infer_rk3588_unquantized.rknn  ch_ppocr_mobile_v20_cls_infer_rk3588_unquantized.rknn ch_PP-OCRv3_rec_infer_rk3588_unquantized.rknn ppocr_keys_v1.txt 12.jpg 1

运行结果如下:

blueberry@poodle:~/FastDeploy/examples/vision/ocr/PP-OCR/rockchip/cpp/build$ ./infer_demo ch_PP-OCRv3_det_infer_rk3588_unquantized.rknn  ch_ppocr_mobile_v20_cls_infer_rk3588_unquantized.rknn ch_PP-OCRv3_rec_infer_rk3588_unquantized.rknn ppocr_keys_v1.txt 12.jpg 1
[INFO] fastdeploy/runtime/backends/rknpu2/rknpu2_backend.cc(81)::GetSDKAndDeviceVersion	rknpu2 runtime version: 1.5.2 (c6b7b351a@2023-08-23T15:28:22)
[INFO] fastdeploy/runtime/backends/rknpu2/rknpu2_backend.cc(82)::GetSDKAndDeviceVersion	rknpu2 driver version: 0.8.2
index=0, name=x, n_dims=4, dims=[1, 960, 960, 3], n_elems=2764800, size=5529600, fmt=NHWC, type=FP16, qnt_type=AFFINE, zp=0, scale=1.000000, pass_through=0
index=0, name=sigmoid_0.tmp_0, n_dims=4, dims=[1, 1, 960, 960], n_elems=921600, size=1843200, fmt=NCHW, type=FP32, qnt_type=AFFINE, zp=0, scale=1.000000, pass_through=0
[INFO] fastdeploy/runtime/runtime.cc(367)::CreateRKNPU2Backend	Runtime initialized with Backend::RKNPU2 in Device::RKNPU.
[INFO] fastdeploy/runtime/backends/rknpu2/rknpu2_backend.cc(81)::GetSDKAndDeviceVersion	rknpu2 runtime version: 1.5.2 (c6b7b351a@2023-08-23T15:28:22)
[INFO] fastdeploy/runtime/backends/rknpu2/rknpu2_backend.cc(82)::GetSDKAndDeviceVersion	rknpu2 driver version: 0.8.2
index=0, name=x, n_dims=4, dims=[1, 48, 192, 3], n_elems=27648, size=55296, fmt=NHWC, type=FP16, qnt_type=AFFINE, zp=0, scale=1.000000, pass_through=0
index=0, name=softmax_0.tmp_0, n_dims=2, dims=[1, 2, 0, 0], n_elems=2, size=4, fmt=UNDEFINED, type=FP32, qnt_type=AFFINE, zp=0, scale=1.000000, pass_through=0
[INFO] fastdeploy/runtime/runtime.cc(367)::CreateRKNPU2Backend	Runtime initialized with Backend::RKNPU2 in Device::RKNPU.
[INFO] fastdeploy/runtime/backends/rknpu2/rknpu2_backend.cc(81)::GetSDKAndDeviceVersion	rknpu2 runtime version: 1.5.2 (c6b7b351a@2023-08-23T15:28:22)
[INFO] fastdeploy/runtime/backends/rknpu2/rknpu2_backend.cc(82)::GetSDKAndDeviceVersion	rknpu2 driver version: 0.8.2
index=0, name=x, n_dims=4, dims=[1, 48, 320, 3], n_elems=46080, size=92160, fmt=NHWC, type=FP16, qnt_type=AFFINE, zp=0, scale=1.000000, pass_through=0
index=0, name=softmax_5.tmp_0, n_dims=4, dims=[1, 40, 6625, 1], n_elems=265000, size=530000, fmt=NCHW, type=FP32, qnt_type=AFFINE, zp=0, scale=1.000000, pass_through=0
[INFO] fastdeploy/runtime/runtime.cc(367)::CreateRKNPU2Backend	Runtime initialized with Backend::RKNPU2 in Device::RKNPU.
[WARNING] fastdeploy/runtime/backends/rknpu2/rknpu2_backend.cc(420)::InitRKNNTensorMemory	The input tensor type != model's inputs type.The input_type need FP16,but inputs[0].type is UINT8
[WARNING] fastdeploy/runtime/backends/rknpu2/rknpu2_backend.cc(420)::InitRKNNTensorMemory	The input tensor type != model's inputs type.The input_type need FP16,but inputs[0].type is UINT8
[WARNING] fastdeploy/runtime/backends/rknpu2/rknpu2_backend.cc(420)::InitRKNNTensorMemory	The input tensor type != model's inputs type.The input_type need FP16,but inputs[0].type is UINT8
det boxes: [[276,174],[285,173],[285,178],[276,179]]rec text: 洗酸兼滋染斜洗免 rec score:0.996582 cls label: 1 cls score: 0.766602
det boxes: [[43,408],[483,390],[483,431],[44,449]]rec text: 洗洗武斜武酸兼滋龈斜洗免 rec score:0.953939 cls label: 0 cls score: 1.000000
det boxes: [[186,456],[399,448],[399,480],[186,488]]rec text: 冏洗泰权地斜武泰滋龈斜洗 rec score:0.994914 cls label: 0 cls score: 1.000000
det boxes: [[18,501],[513,485],[514,537],[18,554]]rec text: 洗久泰酸兼滋龈斜洗免 rec score:0.992969 cls label: 0 cls score: 1.000000
det boxes: [[78,553],[404,541],[404,573],[78,585]]rec text: 洗鼠▏开泰才钧泰滋龈斜洗免 rec score:0.992751 cls label: 0 cls score: 1.000000

Visualized result saved in ./vis_result.jpg

乱码应该是我自己编码问题。

——————————————————————————————————————————————

更新,乱码问题已经得到解决。需要将Ubuntu系统上的rknn-toolkit2版本定为rknn-toolkit2 1.4.2b3+0bdd72ff

可以在官方rknn-toolkit2历史仓库中1.4.0分支下的develop文件夹中找到。密码为:rknn

如果有帮到你给我个赞吧!~

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐