RK3568 NPU RKNN(五):RKNN-ToolKit-lite2板端推理

文章目录

  • 1、前言
  • 2、目标
  • 3、安装RKNN-ToolKit-lite2
    • 3.1、安装环境
    • 3.2、安装RKNN-ToolKit-lite2
    • 3.3、验证
  • 4、完整的测试程序
  • 5、运行测试程序
  • 6、程序拆解
  • 7、总结

1、前言

本文仅记录本人学习过程,不具备教学指导意义。

2、目标

之前提到过,RKNN-Toolkit2-Lite2RKNN-Toolkit2的阉割版,只保留了推理功能,可以直接运行在板卡上。本文目标将下载安装rknn-toolkit-lite2,使用野火提供的示例程序,体验 rknn-toolkit-lite2 在板卡端推理。

3、安装RKNN-ToolKit-lite2

这里使用的是ubuntu系统的板卡,以下命令都是在板卡端执行。

3.1、安装环境

#安装python工具,安装相关依赖和软件包等
sudo apt update
sudo apt-get install python3-dev python3-pip gcc
sudo apt install -y python3-opencv python3-numpy python3-setuptools

3.2、安装RKNN-ToolKit-lite2

# 获取 RKNN-ToolKit-lite2 工程文件
# 可以官网获取:https://github.com/airockchip/rknn-toolkit2/tree/master/rknn-toolkit-lite2
# 这里使用野火提供的
git clone https://gitee.com/LubanCat/lubancat_ai_manual_code.git# 安装 RKNN-ToolKit-lite2 软件工具包
# 我的python版本是3.8
pip3 install packages/rknn_toolkit_lite2-1.5.0-cp38-cp38-linux_aarch64.whl

3.3、验证

root@lubancat:~/lubancat_ai_manual_code/dev_env/rknn_toolkit_lite2# python3
Python 3.8.10 (default, Mar 18 2025, 20:04:55)
[GCC 9.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from rknnlite.api import RKNNLite
>>>

4、完整的测试程序

import urllib
import time
import sys
import numpy as np
import cv2
import platform
from rknnlite.api import RKNNLiteRK3566_RK3568_RKNN_MODEL = 'yolov5s_for_rk3566_rk3568.rknn'
RK3588_RKNN_MODEL = 'yolov5s_for_rk3588.rknn'
RK3562_RKNN_MODEL = 'yolov5s_for_rk3562.rknn'
IMG_PATH = './bus.jpg'OBJ_THRESH = 0.25
NMS_THRESH = 0.45
IMG_SIZE = 640CLASSES = ("person", "bicycle", "car", "motorbike ", "aeroplane ", "bus ", "train", "truck ", "boat", "traffic light","fire hydrant", "stop sign ", "parking meter", "bench", "bird", "cat", "dog ", "horse ", "sheep", "cow", "elephant","bear", "zebra ", "giraffe", "backpack", "umbrella", "handbag", "tie", "suitcase", "frisbee", "skis", "snowboard", "sports ball", "kite","baseball bat", "baseball glove", "skateboard", "surfboard", "tennis racket", "bottle", "wine glass", "cup", "fork", "knife ","spoon", "bowl", "banana", "apple", "sandwich", "orange", "broccoli", "carrot", "hot dog", "pizza ", "donut", "cake", "chair", "sofa","pottedplant", "bed", "diningtable", "toilet ", "tvmonitor", "laptop	", "mouse	", "remote ", "keyboard ", "cell phone", "microwave ","oven ", "toaster", "sink", "refrigerator ", "book", "clock", "vase", "scissors ", "teddy bear ", "hair drier", "toothbrush ")# decice tree for rk356x/rk3588
DEVICE_COMPATIBLE_NODE = '/proc/device-tree/compatible'def get_host():# get platform and device typesystem = platform.system()machine = platform.machine()os_machine = system + '-' + machineif os_machine == 'Linux-aarch64':try:with open(DEVICE_COMPATIBLE_NODE) as f:device_compatible_str = f.read()if 'rk3588' in device_compatible_str:host = 'RK3588'elif 'rk3562' in device_compatible_str:host = 'RK3562'else:host = 'RK3566_RK3568'except IOError:print('Read device node {} failed.'.format(DEVICE_COMPATIBLE_NODE))exit(-1)else:host = os_machinereturn hostdef sigmoid(x):return 1 / (1 + np.exp(-x))def xywh2xyxy(x):# Convert [x, y, w, h] to [x1, y1, x2, y2]y = np.copy(x)y[:, 0] = x[:, 0] - x[:, 2] / 2  # top left xy[:, 1] = x[:, 1] - x[:, 3] / 2  # top left yy[:, 2] = x[:, 0] + x[:, 2] / 2  # bottom right xy[:, 3] = x[:, 1] + x[:, 3] / 2  # bottom right yreturn ydef process(input, mask, anchors):anchors = [anchors[i] for i in mask]grid_h, grid_w = map(int, input.shape[0:2])box_confidence = sigmoid(input[..., 4])box_confidence = np.expand_dims(box_confidence, axis=-1)box_class_probs = sigmoid(input[..., 5:])box_xy = sigmoid(input[..., :2])*2 - 0.5col = np.tile(np.arange(0, grid_w), grid_w).reshape(-1, grid_w)row = np.tile(np.arange(0, grid_h).reshape(-1, 1), grid_h)col = col.reshape(grid_h, grid_w, 1, 1).repeat(3, axis=-2)row = row.reshape(grid_h, grid_w, 1, 1).repeat(3, axis=-2)grid = np.concatenate((col, row), axis=-1)box_xy += gridbox_xy *= int(IMG_SIZE/grid_h)box_wh = pow(sigmoid(input[..., 2:4])*2, 2)box_wh = box_wh * anchorsbox = np.concatenate((box_xy, box_wh), axis=-1)return box, box_confidence, box_class_probsdef filter_boxes(boxes, box_confidences, box_class_probs):"""Filter boxes with box threshold. It's a bit different with origin yolov5 post process!# Argumentsboxes: ndarray, boxes of objects.box_confidences: ndarray, confidences of objects.box_class_probs: ndarray, class_probs of objects.# Returnsboxes: ndarray, filtered boxes.classes: ndarray, classes for boxes.scores: ndarray, scores for boxes."""boxes = boxes.reshape(-1, 4)box_confidences = box_confidences.reshape(-1)box_class_probs = box_class_probs.reshape(-1, box_class_probs.shape[-1])_box_pos = np.where(box_confidences >= OBJ_THRESH)boxes = boxes[_box_pos]box_confidences = box_confidences[_box_pos]box_class_probs = box_class_probs[_box_pos]class_max_score = np.max(box_class_probs, axis=-1)classes = np.argmax(box_class_probs, axis=-1)_class_pos = np.where(class_max_score >= OBJ_THRESH)boxes = boxes[_class_pos]classes = classes[_class_pos]scores = (class_max_score* box_confidences)[_class_pos]return boxes, classes, scoresdef nms_boxes(boxes, scores):"""Suppress non-maximal boxes.# Argumentsboxes: ndarray, boxes of objects.scores: ndarray, scores of objects.# Returnskeep: ndarray, index of effective boxes."""x = boxes[:, 0]y = boxes[:, 1]w = boxes[:, 2] - boxes[:, 0]h = boxes[:, 3] - boxes[:, 1]areas = w * horder = scores.argsort()[::-1]keep = []while order.size > 0:i = order[0]keep.append(i)xx1 = np.maximum(x[i], x[order[1:]])yy1 = np.maximum(y[i], y[order[1:]])xx2 = np.minimum(x[i] + w[i], x[order[1:]] + w[order[1:]])yy2 = np.minimum(y[i] + h[i], y[order[1:]] + h[order[1:]])w1 = np.maximum(0.0, xx2 - xx1 + 0.00001)h1 = np.maximum(0.0, yy2 - yy1 + 0.00001)inter = w1 * h1ovr = inter / (areas[i] + areas[order[1:]] - inter)inds = np.where(ovr <= NMS_THRESH)[0]order = order[inds + 1]keep = np.array(keep)return keepdef yolov5_post_process(input_data):masks = [[0, 1, 2], [3, 4, 5], [6, 7, 8]]anchors = [[10, 13], [16, 30], [33, 23], [30, 61], [62, 45],[59, 119], [116, 90], [156, 198], [373, 326]]boxes, classes, scores = [], [], []for input, mask in zip(input_data, masks):b, c, s = process(input, mask, anchors)b, c, s = filter_boxes(b, c, s)boxes.append(b)classes.append(c)scores.append(s)boxes = np.concatenate(boxes)boxes = xywh2xyxy(boxes)classes = np.concatenate(classes)scores = np.concatenate(scores)nboxes, nclasses, nscores = [], [], []for c in set(classes):inds = np.where(classes == c)b = boxes[inds]c = classes[inds]s = scores[inds]keep = nms_boxes(b, s)nboxes.append(b[keep])nclasses.append(c[keep])nscores.append(s[keep])if not nclasses and not nscores:return None, None, Noneboxes = np.concatenate(nboxes)classes = np.concatenate(nclasses)scores = np.concatenate(nscores)return boxes, classes, scoresdef draw(image, boxes, scores, classes):"""Draw the boxes on the image.# Argument:image: original image.boxes: ndarray, boxes of objects.classes: ndarray, classes of objects.scores: ndarray, scores of objects.all_classes: all classes name."""for box, score, cl in zip(boxes, scores, classes):top, left, right, bottom = boxprint('class: {}, score: {}'.format(CLASSES[cl], score))print('box coordinate left,top,right,down: [{}, {}, {}, {}]'.format(top, left, right, bottom))top = int(top)left = int(left)right = int(right)bottom = int(bottom)cv2.rectangle(image, (top, left), (right, bottom), (255, 0, 0), 2)cv2.putText(image, '{0} {1:.2f}'.format(CLASSES[cl], score),(top, left - 6),cv2.FONT_HERSHEY_SIMPLEX,0.6, (0, 0, 255), 2)def letterbox(im, new_shape=(640, 640), color=(0, 0, 0)):# Resize and pad image while meeting stride-multiple constraintsshape = im.shape[:2]  # current shape [height, width]if isinstance(new_shape, int):new_shape = (new_shape, new_shape)# Scale ratio (new / old)r = min(new_shape[0] / shape[0], new_shape[1] / shape[1])# Compute paddingratio = r, r  # width, height ratiosnew_unpad = int(round(shape[1] * r)), int(round(shape[0] * r))dw, dh = new_shape[1] - new_unpad[0], new_shape[0] - new_unpad[1]  # wh paddingdw /= 2  # divide padding into 2 sidesdh /= 2if shape[::-1] != new_unpad:  # resizeim = cv2.resize(im, new_unpad, interpolation=cv2.INTER_LINEAR)top, bottom = int(round(dh - 0.1)), int(round(dh + 0.1))left, right = int(round(dw - 0.1)), int(round(dw + 0.1))im = cv2.copyMakeBorder(im, top, bottom, left, right, cv2.BORDER_CONSTANT, value=color)  # add borderreturn im, ratio, (dw, dh)if __name__ == '__main__':host_name = get_host()if host_name == 'RK3566_RK3568':rknn_model = RK3566_RK3568_RKNN_MODELelif host_name == 'RK3562':rknn_model = RK3562_RKNN_MODELelif host_name == 'RK3588':rknn_model = RK3588_RKNN_MODELelse:print("This demo cannot run on the current platform: {}".format(host_name))exit(-1)# Create RKNN objectrknn_lite = RKNNLite()# load RKNN modelprint('--> Load RKNN model')ret = rknn_lite.load_rknn(rknn_model)if ret != 0:print('Load RKNN model failed')exit(ret)print('done')# Init runtime environmentprint('--> Init runtime environment')# run on RK356x/RK3588 with Debian OS, do not need specify target.if host_name == 'RK3588':ret = rknn_lite.init_runtime(core_mask=RKNNLite.NPU_CORE_0)else:ret = rknn_lite.init_runtime()if ret != 0:print('Init runtime environment failed!')exit(ret)print('done')# Set inputsimg = cv2.imread(IMG_PATH)#img, ratio, (dw, dh) = letterbox(img, new_shape=(IMG_SIZE, IMG_SIZE))img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)img = cv2.resize(img, (IMG_SIZE, IMG_SIZE))# Inferenceprint('--> Running model')outputs = rknn_lite.inference(inputs=[img])#np.save('./onnx_yolov5_0.npy', outputs[0])#np.save('./onnx_yolov5_1.npy', outputs[1])#np.save('./onnx_yolov5_2.npy', outputs[2])print('done')# post processinput0_data = outputs[0]input1_data = outputs[1]input2_data = outputs[2]input0_data = input0_data.reshape([3, -1]+list(input0_data.shape[-2:]))input1_data = input1_data.reshape([3, -1]+list(input1_data.shape[-2:]))input2_data = input2_data.reshape([3, -1]+list(input2_data.shape[-2:]))input_data = list()input_data.append(np.transpose(input0_data, (2, 3, 0, 1)))input_data.append(np.transpose(input1_data, (2, 3, 0, 1)))input_data.append(np.transpose(input2_data, (2, 3, 0, 1)))boxes, classes, scores = yolov5_post_process(input_data)img_1 = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)if boxes is not None:draw(img_1, boxes, scores, classes)# show outputcv2.imwrite("out.jpg", img_1)#cv2.imshow("post process result", img_1)#cv2.waitKey(0)#cv2.destroyAllWindows()rknn_lite.release()

5、运行测试程序

# 板卡端执行
cd lubancat_ai_manual_code/dev_env/rknn_toolkit_lite2/examples/yolov5_inference
python3 test.py

查看最后生成的out.jpg:

6、程序拆解

  1. 创建rknnlite对象
rknn_lite = RKNNLite()
  1. 加载rknn模型
rknn_lite.load_rknn(rknn_model)
  1. 初始化运行环境
rknn_lite.init_runtime()
  1. 模型推理(Inference)
outputs = rknn.inference(inputs=[img])
  1. 后处理(Post-process)
# post process
input0_data = outputs[0]
input1_data = outputs[1]
input2_data = outputs[2]input0_data = input0_data.reshape([3, -1]+list(input0_data.shape[-2:]))
input1_data = input1_data.reshape([3, -1]+list(input1_data.shape[-2:]))
input2_data = input2_data.reshape([3, -1]+list(input2_data.shape[-2:]))input_data = list()
input_data.append(np.transpose(input0_data, (2, 3, 0, 1)))
input_data.append(np.transpose(input1_data, (2, 3, 0, 1)))
input_data.append(np.transpose(input2_data, (2, 3, 0, 1)))boxes, classes, scores = yolov5_post_process(input_data)img_1 = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
if boxes is not None:draw(img_1, boxes, scores, classes)# show output
cv2.imwrite("out.jpg", img_1)
#cv2.imshow("post process result", img_1)
#cv2.waitKey(0)
#cv2.destroyAllWindows()

7、总结

参考文章:

https://doc.embedfire.com/linux/rk356x/Ai/zh/latest/lubancat_ai/env/toolkit_lite2.html#id3

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/93364.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/93364.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

二分查找。。

1 二分查找二分查找前提是数组有序。先令&#xff0c;left 0 , right 7mid (right left) / 2;如果mid的值大于要查找的值&#xff0c;则right mid - 1&#xff1b;如果小于&#xff0c;left mid 1&#xff1b;如果mid的值等于要查找的值&#xff0c;查找成功。重复步骤2…

Spring Ai 如何配置以及如何搭建

Spring Ai 如何配置以及如何搭建 解释什么是Spring ai 首先&#xff0c;我们用Spring ai 其实不是去了解他的LLM,以及底层用的一些东西&#xff0c;Spring AI,提供给我们的其实是对各种大模型快速调用&#xff0c;提供了大模型API的作用&#xff0c;Spring AI 的核心定位是提…

FCC认证三星XR头显加速全球量产,微美全息AI+AR技术引领智能眼镜硬件创新

据悉&#xff0c;三星(SSNGY.US)XR头显Project Moohan目前已获得美国FCC认证&#xff0c;FCC认证表明该款头显即将上市&#xff0c;之前三星财报会议也表明确认将于今年年底推出XR头显。此前有报道称&#xff0c;该设备将采用索尼旗舰级 OLEDoS 显示屏&#xff0c;像素密度高达…

洛谷P1595讲解(加强版)+错排讲解

前言接我原先的文章&#xff0c;因为一场考试&#xff0c;让我对这道题记忆深刻注&#xff1a;&#xff08;因为那道题&#xff0c;所以80分&#xff09;正文1.分析题目题目&#xff1a;某人写了 n 封信和 n 个信封&#xff0c;如果所有的信都装错了信封。求所有信都装错信封共…

提升化工制造质量的 7 种方法

尽管化工制造属于制造业的一个子类别&#xff0c;但它是一个广泛的范畴&#xff0c;涵盖了基础化学品、树脂和合成纤维、农药和化肥、涂料和粘合剂&#xff0c;甚至消费类化合物&#xff08;如肥皂和清洁化学品&#xff09;等所有领域。尽管这些细分领域差异巨大&#xff0c;但…

从“数据垄断”到“全民共建”:Dataparts如何重构智能时代的数据流通规则?

从“数据垄断”到“全民共建”&#xff1a;Dataparts如何重构智能时代的数据流通规则&#xff1f;在杭州某科技园区的会议室里&#xff0c;一场关于“AI大模型训练数据”的讨论正在激烈进行。某头部AI企业的技术总监指着屏幕上的“对话场景零件库”说&#xff1a;“过去我们花3…

31 HTB Union 机器 - 中等难度

第一阶段 侦查nmap扫描oxdfparrot$ nmap -p- --min-rate 10000 -oA scans/nmap-alltcp 10.10.11.128 Starting Nmap 7.80 ( https://nmap.org ) at 2021-11-19 08:29 EST Nmap scan report for 10.10.11.128 Host is up (0.092s latency). Not shown: 65534 filtered ports POR…

【数据分享】上市公司创新韧性数据(2007-2023)

数据介绍核心看点&#xff1a; 在复杂多变的市场环境中&#xff0c;企业如何通过创新维持竞争力&#xff1f;创新韧性是衡量企业在外部冲击下保持创新活力的关键指标。本文分享2007-2023年上市公司创新韧性数据&#xff0c;为研究企业抗风险能力提供核心支持。数据概览数据名称…

服务器配置开机自启动服务

一、配置启动文件sudo vim /etc/systemd/system/smartailab-backend.service sudo vim /etc/systemd/system/reall3d-frontend.servicesudo vim /etc/systemd/system/Culture_Liquor-backend.servicevim /etc/systemd/system/Culture_Liquor-backend.service内容&#xff1a;[U…

Ubuntu 25.04更新了哪些内容揭秘

2025年4月,Canonical正式推出Ubuntu 25.04 版本,代号"Plucky Puffin(勇敢的海鹦)"。此次发布围绕AI算力强化、桌面交互革新与跨架构支持三大核心方向展开,为开发者、创作者及企业用户带来多项突破性升级。 一、核心系统更新 systemd v257.4带来了重要的上游更新…

PHP反序列化的CTF题目环境和做题复现第2集_POP链构造

1 通过pop参数get方式提交反序列信息 2 题目 http://192.168.1.8/fxl2/fxl2_pop.php <?php highlight_file(__FILE__);class a {protected $var;public function hello(){echo $this->var;} }class b {public $cla;public function __destruct(){$this->cla->…

攻防世界—fakebook(两种方法)

一.审题这边先进行测试&#xff0c;login和join都失败了&#xff0c;所以没获取到什么消息。二.dirsearch工具扫描所以拿dirsearch扫一下&#xff0c;看看有没有什么文件可以访问。python3 dirsearch.py -u url可以看到当前目录下存在flag.php,robots.txt等&#xff0c;访问fla…

AI+物联网如何重塑仓储供应链?3个落地场景与系统架构设计思路

一、引言 在科技飞速发展的当下&#xff0c;AI与物联网技术的融合为仓储供应链领域带来了革新契机。这种融合不仅优化了传统运作模式&#xff0c;还催生出更智能、高效的管理方案&#xff0c;业财一体管理软件也在其中发挥着关键作用。 二、AI物联网在仓储供应链的落地场景 &am…

C++ 内存管理(内存分布 , 管理方式 , new和delete实现原理)

目录 1. C/C内存分布 练习: 2. C语言动态内存管理方式 2.1 malloc/calloc/realloc的区别 2.2 malloc的实现原理 2.3 内存块分布与扩容 3. C动态内存管理方式 3.1 new/delete操作类内置类型 1. new操作内置类型 2. delete操作内置类型 3.2 new/delete操作类自定义类型…

1.2. qemu命令起虚拟机增加网络配置

1. 网络配置 常见的网络模式分为tap网络和基础网络模式两种。 1.1. TAP网络&#xff08;桥接模式&#xff09; 虚拟机直接接入宿主机物理网络&#xff0c;获得独立IP 1.1.1. 使用tap方式起虚拟机网络-netdev tap,idhostnet0,ifnametap0 \-device virtio-net-pci,netdevhostnet0…

分享一个Oracle表空间自动扩容与清理脚本

一、基础环境准备&#xff08;首次执行&#xff09; -- 1. 创建表空间监控表&#xff08;存储使用率、容量等信息&#xff09; create table monitor_tablespace_rate (tbs_name varchar2(50), -- 表空间名total_gb number, -- 总容量(GB)used_gb number, …

Flink Sql 按分钟或日期统计数据量

一、环境版本 环境版本Flink1.17.0Kafka2.12MySQL5.7.33 【注意】Flink 1.13版本增加Cumulate Window&#xff0c;之前版本Flink Sql 没有 Trigger 功能&#xff0c;长时间的窗口不能在中途触发计算&#xff0c;输出中间结果。比如每 10S 更新一次截止到当前的pv、uv。只能用T…

LeetCode 2460.对数组执行操作

给你一个下标从 0 开始的数组 nums &#xff0c;数组大小为 n &#xff0c;且由 非负 整数组成。 你需要对数组执行 n - 1 步操作&#xff0c;其中第 i 步操作&#xff08;从 0 开始计数&#xff09;要求对 nums 中第 i 个元素执行下述指令&#xff1a; 如果 nums[i] nums[i …

深入解析 @nestjs/typeorm的 forRoot 与 forFeature

nestjs/typeorm 是 NestJS 与 TypeORM 集成的官方模块&#xff0c;提供了 forRoot() 和 forFeature() 两个核心静态方法用于配置数据库连接和实体注册。本文将深入解析这两个方法的机制、使用场景和最佳实践。 一、TypeOrmModule.forRoot() - 全局数据库配置 forRoot() 方法用于…

关于simplifyweibo_4_moods数据集的分类问题

本来打算用情感分类数据集拿Transformer模型来练练手&#xff0c;发现训练效果并不好。当我分析了这个数据集的标签后发现问题了&#xff1a; 查看标签的分布&#xff1a; import pandas as pd# 先直接读取数据&#xff0c;不进行后续处理 data_file ~/data/simplifyweibo_4_m…