RKNN YOLO ZOO
Demo: pre-trained yolo to RKNN
Target: radxa zero 3w: RK3566
- Clone zoo
- Clone toolkit v 2.3.2
- Create venv in zoo folder using uv
- Install other dependencies
- Run Convert
- Check on device
| clone zoo | |
|---|---|
| clone toolkit | |
|---|---|
Create virtual environment
- create venv in zoo root folder using
uv
| python virtual environment | |
|---|---|
Tip
The repository has .python-version file that set the version 3.11 when create venv using uv it use it to set the python venv version
install toolkit version
All the version locate in repository packages folder
| install relevant whl package | |
|---|---|
Run convert
| convert | |
|---|---|
Check the model
Copy the code into device, don't forget the mode and source image
Inference code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 | |
flowchart LR
A[Load .rknn model] --> B[Initialize RKNN NPU runtime]
B --> C[Read bus.jpg with OpenCV]
C --> D{Image is 640 x 640?}
D -- No --> X[Stop with size error]
D -- Yes --> E[Convert OpenCV BGR to model RGB]
E --> F[Add batch dimension<br/>shape 1 x 640 x 640 x 3]
F --> G[Run model.inference on the NPU]
G --> H[Raw box and class tensors<br/>at 3 detection scales]
H --> I[Decode DFL box distances]
I --> J[Convert to x1 y1 x2 y2]
J --> K[Flatten and join all scales]
K --> L[Choose best class and score]
L --> M{Score at least OBJ_THRESH?}
M -- No --> N[Discard candidate]
M -- Yes --> O[Apply NMS separately per class]
O --> P[Draw retained boxes and labels]
P --> Q[Save bus_detected.jpg]
Q --> R[Release RKNN runtime]
X --> R
The important data changes are:
cv2.imread()loads the file as BGR, OpenCV's default channel order.cv2.cvtColor(..., cv2.COLOR_BGR2RGB)changes it to RGB, the channel order expected by this model.image[None]adds the batch dimension, changing(640, 640, 3)into(1, 640, 640, 3).model.inference()sends that tensor to the RK3566 NPU. Its result is a collection of raw NumPy tensors, not ready-to-draw boxes.post_process()decodes those tensors, removes low-confidence and overlapping candidates, and returns the final boxes, class IDs, and scores.
Explain output
The run completed successfully. The log contains: - one harmless warning, - detection results, - saved-image path.
Runtime and model information
librknnrtis the RKNN runtime installed on the board.- The driver connects that runtime to the NPU.
- Toolkit 2.3.2 converted the original ONNX model for the RK3566.
static_shapemeans the model accepts its fixed 640 × 640 input shape.
Static-shape warning
This warning is expected for this model. RKNNLite tried to query dynamic input dimensions, but the model was intentionally exported with a fixed shape. The example supplies a 640 × 640 image, so no change is required.
Detections
Each result uses this format:
For example:
| Field | Meaning |
|---|---|
person |
Predicted COCO class. |
(211, 241) |
Top-left corner of the bounding box. |
(282, 506) |
Bottom-right corner of the bounding box. |
0.864 |
Confidence score, approximately 86.4%. |
The model found four people and one bus. The last person has a score of 0.305 and remains because OBJ_THRESH is 0.25. Increase the threshold to reject weaker detections.
The bus box can overlap person boxes because non-maximum suppression runs separately for each class.
Saved result
Open bus_detected.jpg to inspect the bounding boxes drawn over the source image.