记录如何在RK3588板子上跑通paddle的OCR模型
根据官方给的提示
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程序时会用上。
- 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
如果有帮到你给我个赞吧!~