简介:本文详细介绍了YOLO目标检测模型通过ONNX格式在Python推理引擎中的实现方法,涵盖模型转换、环境配置、推理流程优化及性能调优,为开发者提供从部署到优化的全流程技术指导。
YOLO(You Only Look Once)系列模型以其高效的实时目标检测能力闻名,而ONNX(Open Neural Network Exchange)作为跨框架模型交换标准,为YOLO模型的跨平台部署提供了关键支持。通过将PyTorch或TensorFlow训练的YOLO模型转换为ONNX格式,开发者可以:
以YOLOv5为例,其模型结构包含Backbone(CSPDarknet)、Neck(PANet)和Head(检测层)三部分。转换为ONNX后,模型参数以计算图形式存储,保留了完整的推理逻辑。
ONNX Runtime是微软开发的跨平台推理引擎,支持Windows/Linux/macOS系统,提供Python绑定。其核心优势包括:
安装命令:
pip install onnxruntime-gpu # GPU版本pip install onnxruntime # CPU版本
对于NVIDIA GPU用户,TensorRT可通过以下方式提升性能:
转换ONNX模型至TensorRT引擎的流程:
import tensorrt as trtlogger = trt.Logger(trt.Logger.WARNING)builder = trt.Builder(logger)network = builder.create_network(1 << int(trt.NetworkDefinitionCreationFlag.EXPLICIT_BATCH))parser = trt.OnnxParser(network, logger)with open("yolov5s.onnx", "rb") as f:if not parser.parse(f.read()):for error in range(parser.num_errors):print(parser.get_error(error))config = builder.create_builder_config()config.set_memory_pool_limit(trt.MemoryPoolType.WORKSPACE, 1 << 30) # 1GBengine = builder.build_engine(network, config)
以YOLOv5为例,使用export.py导出ONNX模型:
python export.py --weights yolov5s.pt --include onnx --opset 12
关键参数说明:
--opset 12:指定ONNX算子集版本,需≥11以支持YOLOv5的特殊操作。--dynamic:启用动态输入形状,适应不同分辨率输入。
import cv2import numpy as npimport onnxruntime as ortclass YOLOv5Onnx:def __init__(self, model_path):self.session = ort.InferenceSession(model_path, providers=['CUDAExecutionProvider', 'CPUExecutionProvider'])self.input_shape = (640, 640) # 默认输入尺寸def preprocess(self, image):# 调整大小并保持宽高比img0 = cv2.imread(image)img = letterbox(img0, self.input_shape)[0]# 转换为RGB并归一化img = img[:, :, ::-1].transpose(2, 0, 1)img = np.ascontiguousarray(img.astype(np.float32) / 255.0)return img0, img[np.newaxis, ...]def postprocess(self, pred, orig_img):# NMS处理pred = non_max_suppression(pred, conf_thres=0.25, iou_thres=0.45)# 解析检测结果results = []for det in pred:if len(det):det[:, :4] = scale_boxes(self.input_shape, det[:, :4], orig_img.shape[:2]).round()for *xyxy, conf, cls in det:results.append({'bbox': [int(x) for x in xyxy],'score': float(conf),'class': int(cls)})return results
def batch_infer(self, images):inputs = []orig_imgs = []for img in images:orig_img, input_tensor = self.preprocess(img)inputs.append(input_tensor)orig_imgs.append(orig_img)batch_input = np.concatenate(inputs, axis=0)pred = self.session.run(None, {'images': batch_input})[0]return [self.postprocess(pred[i:i+1], orig_imgs[i]) for i in range(len(images))]
import cv2def video_demo(model, video_path):cap = cv2.VideoCapture(video_path)while cap.isOpened():ret, frame = cap.read()if not ret:breakorig_img, input_tensor = model.preprocess(frame)pred = model.session.run(None, {'images': input_tensor})[0]results = model.postprocess(pred, orig_img)# 可视化结果for det in results:x1, y1, x2, y2 = det['bbox']cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 255, 0), 2)cv2.imshow('Detection', frame)if cv2.waitKey(1) & 0xFF == ord('q'):break
在Jetson系列设备上,可通过TensorRT优化实现:
算子不支持错误:
--opset 13重新导出模型。内存不足问题:
set_flag(trt.BuilderFlag.GPU_FALLBACK)启用GPU回退。精度下降问题:
通过ONNX格式与Python推理引擎的结合,YOLO模型可以高效部署在从嵌入式设备到云服务器的各种平台上。开发者应重点关注模型转换的正确性、推理引擎的硬件适配以及预处理/后处理的性能优化,以实现最佳的实际应用效果。