Using the RK3588 Chip NPU: Example of Running PPOCRv4 in Windows 11 Docker

The Objective of This Article

This article will practice the PPOCR example in the RKNN Docker environment and deploy it to the RK3588 development board using the adb tool.

Development Environment Description

  • Host System: Windows 11
  • Target Device: Android development board equipped with the RK3588 chip
  • Core Tools: Docker image containing rknn-toolkit2, rknn_model_zoo, and other tools, ADB debugging tools

PPOCR Directory Structure Description

The directory for the PPOCR example is located at rknn_model_zoo\examples\PPOCR, which contains three subdirectories described as follows:

1. PPOCR-Det

Core Functionality

Implements text area detection, improved based on the DB++ (Dynamic Binarization++) algorithm, supporting multi-scale feature fusion and adaptive threshold prediction.

Technical Features

  • Adaptive Input Image Size controlled by the <span>det_limit_side_len</span> parameter with a maximum side length of 960 pixels, using <span>det_limit_type</span> set to “max” mode for dynamic scaling
  • Post-processing Optimization includes differentiable binarization, Vatti Clipping polygon expansion (<span>det_db_unclip_ratio=1.5</span>), and other modules
  • Multi-algorithm Expansion supports post-processing parameter configuration for detection models such as EAST and SAST

2. PPOCR-Rec

Core Functionality

Implements text content recognition, using the SVTR (Scene Text Recognition with Transformer) architecture, supporting multi-language recognition.

Technical Features

  • Input Specification images are uniformly scaled to <span>3,48,320</span> size, loading a dictionary file containing 6625 characters through <span>rec_char_dict_path</span>
  • Dynamic Sequence Modeling uses a Transformer encoder to process variable-length text, supporting mixed training strategies for algorithms like CRNN and ABINet
  • Quantization Optimization provides an INT8 quantization configuration scheme, compressing the model size from 11.9MB to 3.8MB

3. PPOCR-System

Core Functionality

An end-to-end OCR pipeline system that integrates detection, orientation classification, and recognition in three stages.

Workflow

Using the RK3588 Chip NPU: Example of Running PPOCRv4 in Windows 11 Docker
Insert image description here

Starting the RKNN Docker Environment

# Use the docker run command to create and run the RKNN Toolkit2 container
# and map local files into the container using the -v <host src folder>:<image dst folder> parameter
docker run -t -i --privileged -v /dev/bus/usb:/dev/bus/usb -v D:\rknn\rknn_model_zoo-v2.3.0:/rknn_model_zoo rknn-toolkit2:2.3.0-cp38 /bin/bash

Run the PPOCR-Det Example First

Download ppocrv4_det.onnx

cd /rknn_model_zoo/examples/PPOCR/PPOCR-Det/model
./download_model.sh

Execution Result:

Length: 4771801 (4.5M) [application/octet-stream]
Saving to: './ppocrv4_det.onnx'

./ppocrv4_det.onnx                     100%[============================================================================>]   4.55M  1.36MB/s    in 3.3s

2025-04-09 08:43:41 (1.36 MB/s) - './ppocrv4_det.onnx' saved [4771801/4771801]

Convert ONNX to RKNN Format

cd ../python
# python convert.py <onnx_model> <TARGET_PLATFORM> <dtype(optional)> <output_rknn_path(optional)>
python convert.py ../model/ppocrv4_det.onnx rk3588

Running Result:

I rknn-toolkit2 version: 2.3.0
--> Config model
done
--> Loading model
done
--> Building model
I Loading : 100%|█████████████████████████████████████████████| 342/342 [00:00<00:00, 119289.14it/s]
I OpFusing 0: 100%|██████████████████████████████████████████████| 100/100 [00:00<00:00, 706.50it/s]
I OpFusing 1 : 100%|█████████████████████████████████████████████| 100/100 [00:00<00:00, 340.48it/s]
I OpFusing 0 : 100%|█████████████████████████████████████████████| 100/100 [00:00<00:00, 263.83it/s]
I OpFusing 1 : 100%|█████████████████████████████████████████████| 100/100 [00:00<00:00, 250.24it/s]
I OpFusing 2 : 100%|█████████████████████████████████████████████| 100/100 [00:00<00:00, 167.88it/s]
I GraphPreparing : 100%|███████████████████████████████████████| 214/214 [00:00<00:00, 21065.53it/s]
I Quantizating : 100%|████████████████████████████████████████████| 214/214 [00:02<00:00, 72.65it/s]
I rknn building ...
I rknn building done.
done

# ls ../model/
download_model.sh  ppocrv4_det.onnx  ppocrv4_det.rknn  test.jpg

Run the Android System C++ Example

1. Compile

# go back to the rknn_model_zoo root directory
cd ../../
./build-android.sh -t rk3588 -a arm64-v8a -d PPOCR-Det

Compilation succeeded without a doubt.

./build-android.sh -t rk3588 -a arm64-v8a -d PPOCR-Det
===================================
BUILD_DEMO_NAME=PPOCR-Det
BUILD_DEMO_PATH=examples/PPOCR/PPOCR-Det/cpp
TARGET_SOC=rk3588
TARGET_ARCH=arm64-v8a
BUILD_TYPE=Release
ENABLE_ASAN=OFF
DISABLE_RGA=
INSTALL_DIR=/rknn_model_zoo/install/rk3588_android_arm64-v8a/rknn_PPOCR-Det_demo
BUILD_DIR=/rknn_model_zoo/build/build_rknn_PPOCR-Det_demo_rk3588_android_arm64-v8a_Release
ANDROID_NDK_PATH=/rknn_model_zoo/android-ndk-r19c
===================================
Install the project...
-- Install configuration: "Release"
-- Installing: /rknn_model_zoo/install/rk3588_android_arm64-v8a/rknn_PPOCR-Det_demo/./rknn_ppocr_det_demo
-- Installing: /rknn_model_zoo/install/rk3588_android_arm64-v8a/rknn_PPOCR-Det_demo/model/test.jpg
-- Installing: /rknn_model_zoo/install/rk3588_android_arm64-v8a/rknn_PPOCR-Det_demo/model/ppocrv4_det.rknn
-- Installing: /rknn_model_zoo/install/rk3588_android_arm64-v8a/rknn_PPOCR-Det_demo/lib/librknnrt.so
-- Installing: /rknn_model_zoo/install/rk3588_android_arm64-v8a/rknn_PPOCR-Det_demo/lib/librga.so

2. Push to Development Board

# Switch to root user permissions
adb root
adb remount
adb push install/rk3588_android_arm64-v8a/rknn_PPOCR-Det_demo /data/rknn-test

3. Run Demo on Development Board

adb shell
# Enter the rknn_yolov5_demo directory on the development board
cd /data/rknn-test/rknn_PPOCR-Det_demo/
# Set the library environment
export LD_LIBRARY_PATH=./lib
# Run the executable
./rknn_ppocr_det_demo model/ppocrv4_det.rknn model/test.jpg

Running result is as follows:

rk3588_s:/data/rknn-test/rknn_PPOCR-Det_demo # chmod +x rknn_ppocr_det_demo
/rknn_ppocr_det_demo model/ppocrv4_det.rknn model/test.jpg                                                                                                <
model input num: 1, output num: 1
input tensors:
  index=0, name=x, n_dims=4, dims=[1, 480, 480, 3], n_elems=691200, size=691200, fmt=NHWC, type=INT8, qnt_type=AFFINE, zp=-14, scale=0.018658
output tensors:
  index=0, name=sigmoid_0.tmp_0, n_dims=4, dims=[1, 1, 480, 480], n_elems=230400, size=230400, fmt=NCHW, type=INT8, qnt_type=AFFINE, zp=-128, scale=0.003922
model is NHWC input fmt
model input height=480, width=480, channel=3
origin size=500x500 crop size=496x496
input image: 500 x 500, subsampling: 4:4:4, colorspace: YCbCr, orientation: 1
src width is not 4/16-aligned, convert image use cpu
finish
rknn_run
DRAWING OBJECT
[0]: [(27, 459), (136, 459), (136, 478), (27, 478)] 0.990703
[1]: [(27, 428), (371, 428), (371, 446), (27, 446)] 0.865059
[2]: [(25, 397), (361, 395), (362, 413), (26, 415)] 0.947026
[3]: [(367, 368), (474, 366), (476, 386), (368, 388)] 0.988166
[4]: [(27, 363), (282, 365), (281, 384), (26, 382)] 0.952994
[5]: [(25, 334), (342, 334), (342, 352), (25, 352)] 0.955286
[6]: [(26, 303), (252, 303), (252, 320), (26, 320)] 0.977311
[7]: [(25, 270), (180, 270), (180, 289), (25, 289)] 0.995351
[8]: [(25, 240), (241, 240), (241, 259), (25, 259)] 0.987780
[9]: [(413, 233), (429, 233), (429, 305), (413, 305)] 0.977658
[10]: [(26, 209), (234, 209), (234, 227), (26, 227)] 0.999072
[11]: [(25, 179), (298, 177), (300, 194), (26, 195)] 0.991600
[12]: [(28, 142), (281, 144), (280, 163), (27, 161)] 0.963910
[13]: [(27, 111), (332, 113), (331, 134), (26, 133)] 0.929749
[14]: [(26, 82), (171, 82), (171, 104), (26, 104)] 0.997311
[15]: [(28, 37), (302, 39), (301, 70), (27, 69)] 0.961222
    SAVE TO ./out.jpg
write_image path: ./out.jpg width=500 height=500 channel=3 data=0xb4000079e8295e50

Run the PPOCR-Rec Example Next

Download ONNX Model

cd /rknn_model_zoo/examples/PPOCR/PPOCR-Rec/model
./download_model.sh


Saving to: 'ppocrv4_rec.onnx'

ppocrv4_rec.onnx                       100%[============================================================================>]  10.36M  2.52MB/s    in 6.2s

2025-04-09 09:12:14 (1.67 MB/s) - 'ppocrv4_rec.onnx' saved [10862445/10862445]

Convert to RKNN Format

cd ../python
python convert.py ../model/ppocrv4_rec.onnx rk3588
# output model will be saved as ../model/ppocrv4_rec.rknn

Run C++ Demo (Android Development Board)

1. Compile

# go back to the rknn_model_zoo root directory
cd ../../
./build-android.sh -t rk3588 -a arm64-v8a -d PPOCR-Rec

Compilation succeeded without a doubt.

2. Push to Development Board

adb root
adb remount
adb push .\install\rk3588_android_arm64-v8a\rknn_PPOCR-Rec_demo\ /data/rknn-test

3. Run on Development Board

adb shell
cd /data/rknn-test/rknn_PPOCR-Rec_demo
export LD_LIBRARY_PATH=./lib
./rknn_ppocr_rec_demo model/ppocrv4_rec.rknn model/test.png

Running result:

model input num: 1, output num: 1
input tensors:
  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
output tensors:
  index=0, name=softmax_11.tmp_0, n_dims=3, dims=[1, 40, 6625, 0], n_elems=265000, size=530000, fmt=UNDEFINED, type=FP16, qnt_type=AFFINE, zp=0, scale=1.000000
model is NHWC input fmt
model input height=48, width=320, channel=3
rknn_run
regconize result: JOINT, score=0.994140

Finally Run the PPOCR-System Example

Having downloaded and converted the detection and recognition ONNX models to RKNN format, let’s link the entire process together.

1. Compile

# go back to the rknn_model_zoo root directory
cd ../../
./build-android.sh -t rk3588 -a arm64-v8a -d PPOCR-System

Compilation Result:

Install the project...
-- Install configuration: "Release"
-- Installing: /rknn_model_zoo/install/rk3588_android_arm64-v8a/rknn_PPOCR-System_demo/./rknn_ppocr_system_demo
-- Installing: /rknn_model_zoo/install/rk3588_android_arm64-v8a/rknn_PPOCR-System_demo/model/test.jpg
-- Installing: /rknn_model_zoo/install/rk3588_android_arm64-v8a/rknn_PPOCR-System_demo/model/ppocrv4_det.rknn
-- Installing: /rknn_model_zoo/install/rk3588_android_arm64-v8a/rknn_PPOCR-System_demo/model/ppocrv4_rec.rknn
-- Installing: /rknn_model_zoo/install/rk3588_android_arm64-v8a/rknn_PPOCR-System_demo/lib/librknnrt.so
-- Installing: /rknn_model_zoo/install/rk3588_android_arm64-v8a/rknn_PPOCR-System_demo/lib/librga.so

2. Push to Development Board

adb root
adb remount
adb push .\install\rk3588_android_arm64-v8a\rknn_PPOCR-System_demo\ /data/rknn-test

3. Run on Development Board

adb shell
cd /data/rknn-test/rknn_PPOCR-System_demo
export LD_LIBRARY_PATH=./lib
chmod +x rknn_ppocr_system_demo
./rknn_ppocr_system_demo model/ppocrv4_det.rknn model/ppocrv4_rec.rknn   model/test.jpg

Note: The order of the models must be placed as above. Result:

model input height=48, width=320, channel=3
origin size=500x500 crop size=496x496
input image: 500 x 500, subsampling: 4:4:4, colorspace: YCbCr, orientation: 1
src width is not 4/16-aligned, convert image use cpu

DRAWING OBJECT
[0] @ [(28, 37), (302, 39), (301, 70), (27, 69)]
regconize result: Pure Nutrient Hair Conditioner, score=0.997977
[1] @ [(26, 82), (171, 82), (171, 104), (26, 104)]
regconize result: Product Information/Parameters, score=0.994559
[2] @ [(27, 111), (332, 113), (331, 134), (26, 133)]
regconize result: (45 yuan per kilogram, minimum order of 100 kilograms), score=0.971967
[3] @ [(28, 142), (281, 144), (280, 163), (27, 161)]
regconize result: 22 yuan per bottle, minimum order of 1000 bottles), score=0.981864
[4] @ [(25, 179), (298, 177), (300, 194), (26, 195)]
regconize result: [Brand]: OEM/ODM, score=0.986213
[5] @ [(26, 209), (234, 209), (234, 227), (26, 227)]
regconize result: [Product Name]: Pure Nutrient Hair Conditioner, score=0.996297
[6] @ [(25, 240), (241, 240), (241, 259), (25, 259)]
regconize result: [Product Number]: YM-X-3011, score=0.985657
[7] @ [(413, 233), (429, 233), (429, 305), (413, 305)]
regconize result: ODM/OEM, score=0.992676
[8] @ [(25, 270), (180, 270), (180, 289), (25, 289)]
regconize result: [Net Content]: 220ml, score=0.992010
[9] @ [(26, 303), (252, 303), (252, 320), (26, 320)]
regconize result: [Applicable People]: Suitable for all skin types, score=0.995155
[10] @ [(25, 334), (342, 334), (342, 352), (25, 352)]
regconize result: [Main Ingredients]: Cetyl Stearyl Alcohol, Oat Beta-Glucan, score=0.969624
[11] @ [(27, 363), (282, 365), (281, 384), (26, 382)]
regconize result: Sugar, Cocamidopropyl Betaine, Panthenol, score=0.925781
[12] @ [(367, 368), (474, 366), (476, 386), (368, 388)]
regconize result: (Finished Packaging Materials), score=0.986409
[13] @ [(25, 397), (361, 395), (362, 413), (26, 415)]
regconize result: [Main Function]: Can tighten the hair phospholipid layer, thus achieving, score=0.995605
[14] @ [(27, 428), (371, 428), (371, 446), (27, 446)]
regconize result: Instant and lasting improvement of hair shine, providing sufficient nourishment to dry hair, score=0.997995
[15] @ [(27, 459), (136, 459), (136, 478), (27, 478)]
regconize result: Hair sufficient nourishment, score=0.998616
    SAVE TO ./out.jpg
write_image path: ./out.jpg width=500 height=500 channel=3 data=0xb400007c6db69e50

Leave a Comment