https://www.kendryte.com/k230_canmv/zh/main/zh/ai_dev_doc.html#id11 根据这个里面的例程(windows)修改文件地址后报错如下
C:\Install\Anaconda3\envs\YOLO\python.exe C:\All\PycharmProjects\yolov11\toK230\models_compare.py
Traceback (most recent call last):
File "C:\All\PycharmProjects\yolov11\toK230\models_compare.py", line 119, in <module>
nncase_results = kmodel_inference(kmodel_path,kmodel_input_data,model_input_size)
File "C:\All\PycharmProjects\yolov11\toK230\models_compare.py", line 76, in kmodel_inference
sim.load_model(kmodel)
RuntimeError
进程已结束,退出代码为 1
测试了kmodel应该是没有问题的,如下:
import os
kmodel_path = "./models/numDetect_yolov5su.kmodel"
print("kmodel_path:", kmodel_path)
print("File exists:", os.path.exists(kmodel_path))
with open(kmodel_path, 'rb') as f:
kmodel = f.read()
print("kmodel size:", len(kmodel))
=============================================================================
C:\Install\Anaconda3\envs\YOLO\python.exe C:\All\PycharmProjects\yolov11\toK230\test.py
kmodel_path: ./models/numDetect_yolov5su.kmodel
File exists: True
kmodel size: 9768648
进程已结束,退出代码为 0
尝试了把nncase降级到2.8.3(原来是2.9.0)也没用
import os
import cv2
import numpy as np
import onnxruntime as ort
import nncase
import math
# 参数定义
IMG_PATH = "../numDetect/dataset/data/images/test/0_91.jpg"
MEAN = [0, 0, 0]
STD = [1, 1, 1]
MODEL_INPUT_SIZE = [320, 320]
ONNX_MODEL = "../numDetect/runs/detect/train/weights/best.onnx" # ONNX 模型文件
KMODEL_PATH = "./models/yolov5su.kmodel" # kmodel 模型文件
def get_onnx_input(img_path,mean,std,model_input_size):
# 读取图片,图片数据一般是RGB三通道,颜色范围为[0, 255.0]
image_fp32=cv2.imread(img_path)
# 如果模型输入要求是RGB的,则转换为RGB格式,如果要求是BGR的,则不需要转换
image_fp32=cv2.cvtColor(image_fp32, cv2.COLOR_BGR2RGB)
# 缩放成模型输入大小
image_fp32 = cv2.resize(image_fp32, (model_input_size[0], model_input_size[1]))
# 数据类型为float32,
image_fp32 = np.asarray(image_fp32, dtype=np.float32)
# 数据标准化,先归一化到[0,1]范围内,然后减均值除方差
image_fp32/=255.0
for i in range(3):
image_fp32[:, :, i] -= mean[i]
image_fp32[:, :, i] /= std[i]
# 按照模型输入要求处理成NCHW排布或者NHWC排布
image_fp32 = np.transpose(image_fp32, (2, 0, 1))
return image_fp32.copy()
def get_kmodel_input(img_path,mean,std,model_input_size):
# 读取图片,图片数据一般是RGB三通道,颜色范围为[0, 255.0]
image_uint8=cv2.imread(img_path)
# 如果模型输入要求是RGB的,则转换为RGB格式,如果要求是BGR的,则不需要转换
image_uint8=cv2.cvtColor(image_uint8, cv2.COLOR_BGR2RGB)
# 缩放成模型输入大小
image_uint8 = cv2.resize(image_uint8, (model_input_size[0], model_input_size[1]))
# 数据类型为uint8,因为转换kmodel的时候开启了预处理,并且设定了标准化参数,因此这里的输入就不需要实现标准化了
image_uint8 = np.asarray(image_uint8, dtype=np.uint8)
# 按照模型输入要求处理成NCHW排布或者NHWC排布
image_uint8 = np.transpose(image_uint8, (2, 0, 1))
return image_uint8.copy()
def onnx_inference(onnx_path,onnx_input_data):
# 创建 ONNX 推理会话(加载模型)
ort_session = ort.InferenceSession(onnx_path)
# 获取模型输出名称列表,用于后续调用推理
output_names = []
model_outputs = ort_session.get_outputs()
for i in range(len(model_outputs)):
output_names.append(model_outputs[i].name)
# 获取模型的输入信息
model_input = ort_session.get_inputs()[0] # 第一个输入(通常只有一个)
model_input_name = model_input.name # 输入的名称(键)
model_input_type = np.float32 # 输入数据类型,这里假设是 float32
model_input_shape = model_input.shape # 输入张量的形状(维度)
# 处理输入数据,需确保和模型输入形状一致
model_input_data = onnx_input_data.astype(model_input_type).reshape(model_input_shape)
# 执行推理,传入输入名称和数据,返回所有输出结果
onnx_results = ort_session.run(output_names, { model_input_name : model_input_data })
return onnx_results
def kmodel_inference(kmodel_path,kmodel_input_data,model_input_size):
# 初始化nncase 模拟器
sim = nncase.Simulator()
# 读取kmodel
with open(kmodel_path, 'rb') as f:
kmodel = f.read()
# 加载kmodel
sim.load_model(kmodel)
# 读取输入数据
input_shape = [1, 3, model_input_size[1], model_input_size[0]]
dtype = sim.get_input_desc(0).dtype
# 处理输入数据,需确保和模型输入形状一致
kmodel_input = kmodel_input_data.astype(dtype).reshape(input_shape)
# 设置模拟器输入tensor,此处为单输入
sim.set_input_tensor(0, nncase.RuntimeTensor.from_numpy(kmodel_input))
# 模拟器推理kmodel模型
sim.run()
# 获取推理输出
kmodel_results = []
for i in range(sim.outputs_size):
kmodel_result = sim.get_output_tensor(i).to_numpy() # 转换为numpy数组
kmodel_results.append(kmodel_result) # 保存到列表中
return kmodel_results
def cosine_similarity(onnx_results,kmodel_results):
output_size=len(kmodel_results)
# 将每个输出展成一维,然后计算余弦相似度
for i in range(output_size):
onnx_i=np.reshape(onnx_results[i], (-1))
kmodel_i=np.reshape(kmodel_results[i], (-1))
cos = (onnx_i @ kmodel_i) / (np.linalg.norm(onnx_i, 2) * np.linalg.norm(kmodel_i, 2))
print('output {0} cosine similarity : {1}'.format(i, cos))
return
if __name__ == '__main__':
img_path=IMG_PATH
mean=MEAN
std=STD
model_input_size=MODEL_INPUT_SIZE
# ONNX 模型文件
onnx_model = ONNX_MODEL
# kmodel 模型文件
kmodel_path = KMODEL_PATH
# 生成onnx模型输入数据
onnx_input_data = get_onnx_input(img_path,mean,std,model_input_size)
# 生成kmodel模型输入数据
kmodel_input_data = get_kmodel_input(img_path,mean,std,model_input_size)
# onnx模型推理
onnx_results = onnx_inference(onnx_model,onnx_input_data)
# kmodel模型推理
nncase_results = kmodel_inference(kmodel_path,kmodel_input_data,model_input_size)
# 计算输出相似度
cosine_similarity(onnx_results,nncase_results)