当前位置: 首页 > news >正文

关于c++ trt推理YOLO系列,出现检测框混乱,集中左上角的问题

先说原因:维度错乱

  1. 正确解析输出维度:确认输出张量的形状是[1, 84, 8400],其中84是每个锚点的参数,8400是锚点数量。因此,signalResultNum应为84,strideNum为8400。

  2. 数据转置由于OpenCV的cv::Mat是按行优先存储的,而模型输出可能按通道优先排列,因此需要转置数据,使得每行对应一个锚点的所有参数。

    // 原始输出维度应为[1,84,8400]
    nvinfer1::Dims output_dims = output_bindings[0].dims;
    const int num_classes = output_dims.d[1] - 4;  // 80
    const int num_anchors = output_dims.d[2];      // 8400
    
    // 正确创建数据矩阵(行列转置)
    cv::Mat output_mat(num_classes + 4, num_anchors, CV_32F, output_data);
    cv::Mat transposed_mat;
    cv::transpose(output_mat, transposed_mat);  // 转换为[8400,84]
    

    如果你用的是YOLO的官方代码:位置原代码inference.cpp第224行,后处理部分

        int strideNum = outputNodeDims[1];//8400
        int signalResultNum = outputNodeDims[2];//84
        std::vector<int> class_ids;
        std::vector<float> confidences;
        std::vector<cv::Rect> boxes;
        cv::Mat rawData;
        if (modelType == YOLO_DETECT_V8)
        {
            // FP32
            rawData = cv::Mat(strideNum, signalResultNum, CV_32F, output);
        }
        else
        {
            // FP16
            rawData = cv::Mat(strideNum, signalResultNum, CV_16F, output);
            rawData.convertTo(rawData, CV_32F);
        }
 
 
        float* data = (float*)rawData.data;

修改为 

        int strideNum = outputNodeDims[2];//8400
        int signalResultNum = outputNodeDims[1];//84
        std::vector<int> class_ids;
        std::vector<float> confidences;
        std::vector<cv::Rect> boxes;
        cv::Mat rawData;
        cv::Mat transposed_output;
        if (modelType == YOLO_DETECT_V8)
        {
            // FP32
            //rawData = cv::Mat(strideNum, signalResultNum, CV_32F, output);
            rawData = cv::Mat(signalResultNum, strideNum, CV_32F, output);
            cv::transpose(rawData, transposed_output);
        }
        else
        {
            // FP16
            rawData = cv::Mat(signalResultNum, strideNum, CV_16F, output);
            rawData.convertTo(rawData, CV_32F);
            cv::transpose(rawData, transposed_output);
        }
 
 
        //float* data = (float*)rawData.data;
        float* data = (float*)transposed_output.data;

 

网上抄录的野路子代码,可以把原因告诉deepseek,让他修改代码。

相关文章:

  • git技法-对比master和release两个版本差异提交
  • 搭建redis遇到问题:
  • PVE如何查看某块硬盘被哪些虚拟机使用
  • 使用axios发请求
  • 华为项目管理“六步一法”方法论全解析:目标确认、项目活动分解与日事清系统协同
  • 基于51单片机的贪吃蛇小游戏proteus仿真
  • 通过 C# 提取PDF文档中的图片
  • C++ | 文件读写(ofstream/ifstream/fstream)
  • 谷歌TV认证,谷歌TADA认证,谷歌电视认证介绍
  • C++ | 类模板
  • DBAPI设置服务器开机自启动
  • DeepSeek 助力心理医生小程序赋能!心理咨询小程序 线上咨询平台搭建
  • 如何保障话费api接口的稳定性?
  • 最新扣子(Coze)案例教程:最新抖音视频文案提取方法替代方案,音频视频提取文案插件制作,手把手教学,完全免费教程
  • 基于web的生产过程执行管理系统(源码+lw+部署文档+讲解),源码可白嫖!
  • 解决docker部署的容器第二天访问报错139的问题
  • 高密度任务下的挑战与破局:数字样机助力火箭发射提效提质
  • C#:接口(interface)
  • 【vue3】黑马小兔鲜儿项目uniapp navigationStyle
  • 常用学术期刊/会议查询工具