OpenCV 调用自定义训练的 YOLO-V8 Onnx 模型

一、YOLO-V8 转 Onnx

在本专栏的前面几篇文章中,我们使用 ultralytics 公司开源发布的 YOLO-V8 模型,分别 Fine-Tuning 实验了 目标检测、关键点检测、分类 任务,实验后发现效果都非常的不错,但是前面的演示都是基于 ultralytics 框架实现的,如果要发布到移动端或服务端,就需要考虑通用开放格式了,比如 Onnx 格式。

Onnx 格式是一种开放格式,用于表示深度学习模型。它是由微软,亚马逊和Facebook共同开发的,目的是为了促进不同深度学习框架和工具之间的模型互操作性。通过Onnx,开发人员可以更容易地在不同的深度学习框架之间转换模型,例如从PyTorch到TensorFlow,反之亦然。

而 ultralytics 框架针对格式的转换已经做好了封装,只需要通过 model.export 方法,便可以转到多种不同格式的模型,格式如下:

格式 format 模型 元数据 论据
PyTorch - yolov8n.pt ✅ -
TorchScript torchscript yolov8n.torchscript ✅ imgsz, optimize, batch
ONNX onnx yolov8n.onnx ✅ imgsz, half, dynamic, simplify, opset, batch
OpenVINO openvino yolov8n_openvino_model/ ✅ imgsz, half, int8, batch
TensorRT engine yolov8n.engine ✅ imgsz, half, dynamic, simplify, workspace, int8, batch
CoreML coreml yolov8n.mlpackage ✅ imgsz, half, int8, nms, batch
TF SavedModel saved_model yolov8n_saved_model/ ✅ imgsz, keras, int8, batch
TF GraphDef pb yolov8n.pb ❌ imgsz, batch
TF 轻型 tflite yolov8n.tflite ✅ imgsz, half, int8, batch
TF 边缘TPU edgetpu yolov8n_edgetpu.tflite ✅ imgsz
TF.js tfjs yolov8n_web_model/ ✅ imgsz, half, int8, batch
PaddlePaddle paddle yolov8n_paddle_model/ ✅ imgsz, batch
NCNN ncnn yolov8n_ncnn_model/ ✅ imgsz, half, batch

下面使用前面做过的人脸检测模型,转为 Onnx 格式,并使用 OpenCV 运行推理,该模型的训练过程可以参考下面文章:

基于 YOLO V8 Fine-Tuning 训练自定义的目标检测模型(人脸检测)

下面过程使用的依赖版本如下:

shell 复制代码
ultralytics==8.1.37
opencv-python==4.7.0.68
onnx==1.16.1

将 YOLO-V8 默认的 Pytorch 模型转为 Onnx 模型 :

python 复制代码
from ultralytics import YOLO

model = YOLO("runs/detect/train/weights/best.pt")

model.export(format="onnx", imgsz=[640,640], opset=12)

运行后可以在 runs/detect/train/weights/ 下看到 best.onnx 模型:

二、OpenCV 调用 Onnx 模型

OpenCV 的 dnn 模块提供了 readNetFromONNX ,可以方便的读取 Onnx 模型,整个运行示例过程如下:

python 复制代码
import cv2
import numpy as np

onnx_model_path = "runs/detect/train/weights/best.onnx"
input_shape = (640, 640)
net = cv2.dnn.readNetFromONNX(onnx_model_path)
model_classify = ["face"]


def recognize(img_path, threshold=0.5):
    img = cv2.imread(img_path)
    blob = cv2.dnn.blobFromImage(img, 1 / 255.0, input_shape, swapRB=True, crop=False)
    net.setInput(blob)

    output = net.forward()
    output = output.transpose((0, 2, 1))

    height, width, _ = img.shape
    x_factor, y_factor = width / input_shape[0], height / input_shape[1]

    classifys, scores, boxes = [], [], []
    for i in range(output[0].shape[0]):
        box = output[0][i]
        _, _, _, max_idx = cv2.minMaxLoc(box[4:])
        class_id = max_idx[1]
        score = box[4:][class_id]
        if (score > threshold):
            scores.append(score)
            classifys.append(model_classify[int(class_id)])
            x, y, w, h = box[0].item(), box[1].item(), box[2].item(), box[3].item()
            x = int((x - 0.5 * w) * x_factor)
            y = int((y - 0.5 * h) * y_factor)
            w = int(w * x_factor)
            h = int(h * y_factor)
            box = np.array([x, y, w, h])
            boxes.append(box)

    indexes = cv2.dnn.NMSBoxes(boxes, scores, 0.25, 0.45)
    for i in indexes:
        classify, score, box = classifys[i], scores[i], boxes[i]
        print(class_id, score, box)
        x, y, w, h = box[0], box[1], box[2], box[3]
        cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 3)
        label = f'{classify}: {score:.2f}'
        cv2.putText(img, label, (x, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)

    cv2.imshow("img", img)
    cv2.waitKey(0)


if __name__ == '__main__':
    recognize('data/images/10.jpg',0.3)

运行效果示例:

相关推荐
如若12329 分钟前
TRACER 论文解读与复现:面向 ICU 长时程患者监测的多模态 Harness 架构、时序证据建模与工具增强推理
人工智能·深度学习·计算机视觉
qq_25294131682 小时前
无人机视角公路两侧滑坡检测数据集 | 公路巡检 滑坡检测 地质灾害 无人机航拍9302期
yolo·目标检测·目标跟踪·无人机·地质灾害·无人机视角·滑坡检测
深蓝AI2 小时前
无头浏览器不必从 Chrome 改:Lightpanda 用 Zig 从零造,100 个页面只占 123MB 内存
人工智能·程序员
奈落244 小时前
AI辅助的另一面:从2026年国际AI安全报告的“故障”清单到国内专家的可靠性短板,自主行动的Agent为什么更难及时干预
人工智能·安全·agent·本地部署·ai 办公
火山引擎开发者社区6 小时前
eMudhra 证书失陷:容器用户最容易忽略的镜像信任链漏洞
人工智能
LabVIEW开发7 小时前
LabVIEW 机载 DIAL:每秒万次甲烷测量
人工智能·labview·labview知识·labview功能·labview程序
飞猫的边缘AI8 小时前
英特尔量子生意
人工智能·量子计算·边缘ai
深蓝AI8 小时前
桌面 Agent 缺的不是视觉:Vercel 开源 agent-desktop,用无障碍树 ref 替代截图坐标
人工智能·程序员
镜子AI8 小时前
镜子AI 技术复盘:三条自动化链路上的“停止条件“设计
运维·人工智能·自动化
向哆哆9 小时前
羊行为目标检测数据集:4类别、2,000张图像 | 目标检测
人工智能·yolo·目标检测·目标跟踪