到目前为止关于在 k230 上部署并运行 obb 模型的进展如何了?我现在卡在后处理函数的编写上面,请问有这方面的参考资料吗?

Viewed 186

我现在在 k230 上编写后处理函数,但是到目前为止进展非常缓慢。在网上我只看到几篇帖子在讨论如何在 k230 上运行 obb。这些帖子都没有给出有用的解决方法,只是告诉你要自己编写前后处理函数。下面我说说目前我得到的进展。

我在嘉楠官方的 yolo 大作战一文的说明参考下,成功训练好了 obb.pt 并转换成 obb.onnx。这个模型是基于 yolo11-obb.pt 为权重来训练的,数据集是 yolo 官方的 DOTA8 是 DOTA 数据集中较小的 8 幅图像子集,用于测试和持续集成(CI) 检查。我参考 yolo 大作战里的目标检测工具成功把 onnx 转换成 kmodel 并部署到 k230 中了。

k230 里我参考官方自带的 yolov8 目标检测来编写 obb 的代码。期间我让 AI DeepSeek 按照需求帮我写。由于我对一些算法不太熟悉,众所周知 AI 写出的内容和训练他的语料有关,特别是 np 库。有很多函数 k230 都不支持,一些函数的调用方式也不同。后面我才知道 k230 使用的不是标准的 np 库。这样又大大增加了难度。

现在我毫无头绪。AI 也无法给我帮助(他只会复制网上的文字)

请帮帮我。

我在官方 GitHub 上发现了类似的问题,里面提到在模型里开启 nms
https://github.com/ultralytics/ultralytics/issues/19088

5 Answers

你需要了解一下obb的后处理流程,比如模型输出有w/32*h/32+w/16*w/16+w/8*w/8个框,每个框是class_num+5维,也就是坐标+旋转角度,yolov8n-obb.onnx模型的如果是320*320的输入,那么一共有框的总数10*10+20*20+40*40=2100,官方模型是有15个类别,因此每个框的维度是20维。所以yolov8n-obb.onnx的模型输出是1*20*2100。你首先要通过transpose转换成2100*20,这样方便连续取20个数据作为一个框的内容,你需要了解20维中,哪些是位置,哪个值是旋转角度,哪些值是分类置信度。然后如何从这些数据中过滤置信度不符合的框,过滤重叠框。然后如何将旋转角度和坐标转换成四条线的首尾坐标(因为不是标准的矩形框,需要画四条连续的直线)。上述信息都需要你从yolo官方的代码中debug获取。了解了这些,然后才是在k230上写后处理,这个过程你遇到问题再提出来。

我在官方 GitHub 上发现了类似的问题,里面提到在模型里开启 nms
https://github.com/ultralytics/ultralytics/issues/19088

关于模型输出数据格式,需要在官方的 obb 源码上 debug 获取吗?目前我卡了几天了毫无进展。哪里可以获取 obb 模型的数据输出格式,使用 print 输出一大堆数据,无法分清哪些类型的数据。您能给我个大致的思路吗?从输入图片到绘制结果涉及到的一些步骤。

现在我主要在 RTOS 下编写 obb。原因是 Canmv 的一些算法无法满足要求

我在官方 GitHub 上发现了类似的问题,里面提到在模型里开启 nms
https://github.com/ultralytics/ultralytics/issues/19088

下面是我处理的一些步骤
把 yolo11n-obb.pt 转成 yolo11n-obb.onnx 并开启 nms

yolo export model=yolo11n-obb.pt format=onnx nms=True

运行下面的 python 程序测试模型输出

import cv2
import numpy as np
import onnxruntime as ort

if __name__ == "__main__":

    # 加载模型
    session = ort.InferenceSession("yolov8n-obb.onnx", providers=["CPUExecutionProvider"])

    # 获取输入输出信息
    for input in session.get_inputs():
        print(f"Input  Name: {input.name}, Shape: {input.shape}, Type: {input.type}")

    for output in session.get_outputs():
        print(f"Output Name: {output.name}, Shape: {output.shape}, Type: {output.type}")

    # 1. 加载测试图像并预处理
    img = cv2.imread("boats.jpg")
    blob = cv2.dnn.blobFromImage(img, 1/255.0, (1024, 1024), swapRB=True)

    # 2. 运行推理
    outputs = session.run(None, {session.get_inputs()[0].name: blob})

    # 3. 分析输出
    print("输出张量形状:", outputs[0].shape)  # 例如 (1, 10, 6)
    print("示例输出数据(前3个检测结果):\n", outputs[0][0, :3, :])

输出结果

Input  Name: images, Shape: [1, 3, 1024, 1024], Type: tensor(float)
Output Name: output0, Shape: [1, 300, 7], Type: tensor(float)
输出张量形状: (1, 300, 7)
示例输出数据(前3个检测结果):
 [[9.5551410e+02 5.4617480e+02 7.8908127e+01 2.7469975e+01 8.4804726e-01
  1.0000000e+00 7.3035687e-01]
 [9.4972351e+02 5.8845270e+02 7.3113594e+01 2.6608990e+01 8.4455013e-01
  1.0000000e+00 6.6087908e-01]
 [8.6364545e+02 9.5005072e+02 7.6179825e+01 2.9771505e+01 8.3805233e-01
  1.0000000e+00 6.6160357e-01]]

搞清楚输出的7个值分别是什么

按照https://github.com/ultralytics/ultralytics/issues/19088
里的讨论好像是 x1, y1, x2, y2, conf, label, angle
这些值得到了,下一步该怎么做?

我成功在 PC 端测试 onnx 满足需求了,但是在导出 kmodel 发现没有对应的 onnx 算子,这该如何解决?