You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Yolov7模型转ONNX后用OpenCV部署出现NonMaxSuppression层报错

问题分析与解决方案

报错原因

  1. 模型结构不兼容:Yolov7默认导出的ONNX模型内置了NonMaxSuppression(NMS)层,但你的代码是针对Yolov5设计的——Yolov5导出的ONNX输出原始检测框,由代码手动做NMS,两者输出结构完全不同。
  2. OpenCV版本限制:你使用的OpenCV 4.5.5对ONNX标准的NMS层支持不完善,无法解析Yolov7内置的NMS节点。

解决方案一:重新导出不带内置NMS的Yolov7 ONNX模型

直接导出和Yolov5输出格式一致的模型,这样可以完全复用你现有的后处理代码。

在Yolov7项目根目录下执行导出命令,添加--no-nms参数禁用内置NMS:

python export.py --weights runs/train/exp/weights/best.pt --include onnx --simplify --opset 12 --no-nms
  • --no-nms:禁用模型内置的NMS层
  • --opset 12:指定ONNX算子版本,提升兼容性
  • --simplify:简化ONNX模型结构

导出完成后,用新生成的ONNX文件替换原来的data.onnx,原代码无需修改即可运行。


解决方案二:修改代码适配带内置NMS的Yolov7模型

如果不想重新导出模型,可调整后处理逻辑,直接解析模型输出的NMS结果:

替换原代码中的Detect函数为以下内容:

def Detect():
    net = cv2.dnn.readNet(path+"Config/data.onnx")
    
    # 处理图像,保持输入尺寸和模型一致
    blob = cv2.dnn.blobFromImage(img , 1/255.0, (640, 640), swapRB=True)
    net.setInput(blob)
    # Yolov7带NMS的ONNX输出是4个张量:[num_detections, boxes, scores, classes]
    num_detections, boxes, scores, classes = net.forward(net.getUnconnectedOutLayersNames())

    class_list = []
    with open(path+"Config/obj.names", "r") as f:
        class_list = [cname.strip() for cname in f.readlines()]
    
    image_width, image_height, _ = img.shape
    x_factor = image_width / 640
    y_factor =  image_height / 640

    # 解析检测结果
    for i in range(int(num_detections[0][0])):
        score = scores[0][i]
        if score < 0.55:
            continue
        class_id = int(classes[0][i])
        box = boxes[0][i]
        
        # 转换坐标到原始图像尺寸
        x1 = int(box[0] * x_factor)
        y1 = int(box[1] * y_factor)
        x2 = int(box[2] * x_factor)
        y2 = int(box[3] * y_factor)
        box = [x1, y1, x2-x1, y2-y1]
        
        allProductsArray.append(class_list[class_id])
        # 绘制检测框和标签
        cv2.rectangle(img, (x1, y1), (x2, y2), (0, 255, 255), 2)
        cv2.rectangle(img, (x1, y1 - 20), (x2, y1), (0, 255, 255), -1)
        cv2.putText(img, class_list[class_id], (x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, .5, (0,0,0))
        cv2.putText(img, f"{score:.2f}", (x1+60, y1), cv2.FONT_HERSHEY_SIMPLEX, .6, (0,0,0))

额外建议

如果选择方案二,建议升级OpenCV到4.6.0及以上版本,新版本对ONNX算子的支持更完善,能避免很多层解析问题。

内容的提问来源于stack exchange,提问作者techgtec

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 18:58:06