OAK相机如何将yolox模型转换成blob格式?(0.1.1pre 及之后版本)

news/2024/7/11 0:59:57 标签: 计算机视觉, 人工智能, depthai, OAK相机, YOLO

编辑:OAK中国
首发:oakchina.cn
喜欢的话,请多多👍⭐️✍
内容可能会不定期更新,官网内容都是最新的,请查看首发地址链接。

▌前言

Hello,大家好,这里是OAK中国,我是助手君。

最近咱社群里有几个朋友在将yolox转换成blob的过程有点不清楚,所以我就写了这篇博客。(请夸我贴心!咱的原则:合理要求,有求必应!)

1.其他Yolo转换及使用教程请参考
2.检测类的yolo模型建议使用在线转换(地址),如果在线转换不成功,你再根据本教程来做本地转换。

.pth 转换为 .onnx

可以使用预训练模型(onnx) releases

或者使用 YOLOX 自带的 export_onnx 将 pytorch 模型转换为 onnx 模型

可参考 Convert Your Model to ONNX

简单示例

python3 tools/export_onnx.py --output-name yolox_nano.onnx -n yolox_nano-s -c yolox_nano.pth

▌编辑 ONNX 模型

可以使用 Netron 查看模型结构

在这里插入图片描述

我们需要的是上图红框标出的 3 个 Concat 层,并将其命名为 output1_yolov6,output2_yolov6,output3_yolov6。(我们使用 oak 中解析 anchor free 的预制方法(yolov6))

# coding=utf-8
import onnx

onnx_model = onnx.load("yolox_nano.onnx")

concat_indices = []
for i, n in enumerate(onnx_model.graph.node):
    if "Concat" in n.name:
        concat_indices.append(i)
input1, input2, input3 = concat_indices[-4:-1]

onnx_model.graph.node[input1].name = 'output1_yolov6'
onnx_model.graph.node[input2].name = 'output2_yolov6'
onnx_model.graph.node[input3].name = 'output3_yolov6'


onnx.save(onnx_model, "yolox_nano.onnx")

在这里插入图片描述

▌转换

openvino 本地转换

onnx -> openvino

mo 是 openvino_dev 2022.1 中脚本,

安装命令为 pip install openvino-dev

mo --input_model yolox_nano.onnx --reverse_input_channel --output "output1_yolov6,output2_yolov6,output3_yolov6"

openvino -> blob

<path>/compile_tool -m yolox_nano.xml \
-ip U8 -d MYRIAD \
-VPU_NUMBER_OF_SHAVES 6 \
-VPU_NUMBER_OF_CMX_SLICES 6

在线转换

blobconvert 网页 http://blobconverter.luxonis.com/

  • 进入网页,按下图指示操作:

在这里插入图片描述

  • 修改参数,转换模型:

在这里插入图片描述

  1. 选择 onnx 模型
  2. 修改 optimizer_params--data_type=FP16 --reverse_input_channel --output=output1_yolov6,output2_yolov6,output3_yolov6
  3. 修改 shaves6
  4. 转换

blobconverter python 代码

blobconverter.from_onnx(
            "yolox_nano.onnx",	
            optimizer_params=[
                "--reverse_input_channel",
                "--output=output1_yolov6,output2_yolov6,output3_yolov6",
            ],
            shaves=6,
        )

blobconvert cli

	blobconverter --onnx yolox_nano.onnx -sh 6 -o . --optimizer-params "reverse_input_channel --output=output1_yolov6,output2_yolov6,output3_yolov6"

▌DepthAI 示例

正确解码需要可配置的网络相关参数:

  • setNumClasses - YOLO 检测类别的数量
  • setIouThreshold - iou 阈值
  • setConfidenceThreshold - 置信度阈值,低于该阈值的对象将被过滤掉
import cv2
import depthai as dai
import numpy as np

model = dai.OpenVINO.Blob("yolox_nano.blob")
dim = model.networkInputs.get("images").dims
W, H = dim[:2]
labelMap = [
    # "class_1","class_2","..."
    "class_%s"%i for i in range(80)
]

# Create pipeline
pipeline = dai.Pipeline()

# Define sources and outputs
camRgb = pipeline.create(dai.node.ColorCamera)
detectionNetwork = pipeline.create(dai.node.YoloDetectionNetwork)
xoutRgb = pipeline.create(dai.node.XLinkOut)
nnOut = pipeline.create(dai.node.XLinkOut)

xoutRgb.setStreamName("rgb")
nnOut.setStreamName("nn")

# Properties
camRgb.setPreviewSize(W, H)
camRgb.setResolution(dai.ColorCameraProperties.SensorResolution.THE_1080_P)
camRgb.setInterleaved(False)
camRgb.setColorOrder(dai.ColorCameraProperties.ColorOrder.BGR)
camRgb.setFps(40)

# Network specific settings
detectionNetwork.setBlob(model)
detectionNetwork.setConfidenceThreshold(0.5)
detectionNetwork.setNumClasses(80)
detectionNetwork.setCoordinateSize(4)
detectionNetwork.setAnchors([])
detectionNetwork.setAnchorMasks({})
detectionNetwork.setIouThreshold(0.5)

# Linking
camRgb.preview.link(detectionNetwork.input)
camRgb.preview.link(xoutRgb.input)
detectionNetwork.out.link(nnOut.input)

# Connect to device and start pipeline
with dai.Device(pipeline) as device:
    # Output queues will be used to get the rgb frames and nn data from the outputs defined above
    qRgb = device.getOutputQueue(name="rgb", maxSize=4, blocking=False)
    qDet = device.getOutputQueue(name="nn", maxSize=4, blocking=False)

    frame = None
    detections = []
    color2 = (255, 255, 255)

    # nn data, being the bounding box locations, are in <0..1> range - they need to be normalized with frame width/height
    def frameNorm(frame, bbox):
        normVals = np.full(len(bbox), frame.shape[0])
        normVals[::2] = frame.shape[1]
        return (np.clip(np.array(bbox), 0, 1) * normVals).astype(int)

    def displayFrame(name, frame):
        color = (255, 0, 0)
        for detection in detections:
            bbox = frameNorm(frame, (detection.xmin, detection.ymin, detection.xmax, detection.ymax))
            cv2.putText(frame, labelMap[detection.label], (bbox[0] + 10, bbox[1] + 20), cv2.FONT_HERSHEY_TRIPLEX, 0.5, 255)
            cv2.putText(frame, f"{int(detection.confidence * 100)}%", (bbox[0] + 10, bbox[1] + 40), cv2.FONT_HERSHEY_TRIPLEX, 0.5, 255)
            cv2.rectangle(frame, (bbox[0], bbox[1]), (bbox[2], bbox[3]), color, 2)
        # Show the frame
        cv2.imshow(name, frame)

    while True:
        inRgb = qRgb.tryGet()
        inDet = qDet.tryGet()

        if inRgb is not None:
            frame = inRgb.getCvFrame()

        if inDet is not None:
            detections = inDet.detections


        if frame is not None:
            displayFrame("rgb", frame)

        if cv2.waitKey(1) == ord('q'):
            break

▌参考资料

https://www.oakchina.cn/2023/02/23/yolox-blob/
https://docs.oakchina.cn/en/latest/
https://www.oakchina.cn/selection-guide/


OAK中国
| OpenCV AI Kit在中国区的官方代理商和技术服务商
| 追踪AI技术和产品新动态

戳「+关注」获取最新资讯↗↗


http://www.niftyadmin.cn/n/96254.html

相关文章

高/低压供配电系统设计——安科瑞变电站电力监控系统的应用

摘 要&#xff1a;在电力系统的运行过程中&#xff0c;变电站作为整个电力系统的核心&#xff0c;在保证电力系统可靠的运行方面起着至关重要的作用&#xff0c;基于此需对变电站监控系统的特点进行分析&#xff0c;结合变电站监控系统的功能需求&#xff0c;对变电站电力监控系…

Prescriptive Analytics for Flexible Capacity Management

3 本节根据Netessine等人&#xff08;2002年&#xff09;和Bassok等人&#xff08;1999年&#xff09;对我们解决的容量规划问题进行了正式描述。考虑一家以pi&#xff08;I1&#xff0c;…&#xff0c;I&#xff09;的单价提供I服务的公司。在每个计划周期t∈{1&#xff0c;……

Web前端学习:二

二一&#xff1a;文字font-size样式 font-size&#xff1a;**px 控制文字大小&#xff0c;可精准控制大小 默认样式medium&#xff0c;中等的 large&#xff0c;大一号 x-large&#xff0c;再大一号 xx-large&#xff0c;再大一号 small&#xff0c;小一号 <!DOCTYPE html…

JavaWeb--JavaScript

JavaScript1 JavaScript简介2 JavaScript引入方式2.1 内部脚本2.2 外部脚本3 JavaScript基础语法3.1 书写语法3.2 输出语句3.3 变量3.4 数据类型3.5 运算符3.5.1 \\ 和 区别3.5.2 类型转换3.6 流程控制语句3.6.1 if 语句3.6.2 switch 语句3.6.3 for 循环语句3.6.4 while 循环语…

WindowsPowerShell 停止、启动、暂停和重启服务、卸载服务

PowerShell 停止、启动、暂停和重启服务、卸载服务 PowerShell 停止、启动、暂停和重启服务 官文 powershell卸载服务 官文 目录PowerShell 停止、启动、暂停和重启服务、卸载服务停止、启动、暂停和重启停止服务启动服务暂停服务重启服务卸载移除服务停止、启动、暂停、重启…

【玩家心得】Smurf Society 游戏攻略

在深林的深处&#xff0c;生活着一群无忧无虑、快乐的小精灵&#xff0c;浑身蓝色&#xff0c;叫做蓝精灵。蓝精灵住在自己村子里蘑菇屋里&#xff0c;精灵爸爸、精灵妹妹、笨笨、乐乐等使得精灵村每天都欢声笑语。可是&#xff0c;在森林深处的城堡里住着一个邪恶的巫师格格巫…

飞鹅打印机怎么样?飞鹅打印机好用吗?飞鹅打印机怎么知道订单是否漏单?

外卖打印机怎么选?飞鹅打印机好用吗&#xff1f;飞鹅智能云打印机产品专注于云打印的解决方案和技术服务提供。2019 年飞鹅已经成为国内先进的云打印服务提供商&#xff0c;主要是服务美团、饿了么客户&#xff0c;产品主要优势&#xff1a;自动接单、自动打印&#xff0c;无需…

canvas初学2

一、碰撞检测 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"widthdevice-width,…