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

C++中将OpenCV Mat转为DNN张量及blobFromImage维度报错如何解决

问题修复方案

核心问题根因

你收到的报错是因为生成的输入张量维度完全不符合模型要求,从报错日志可以看到当前生成的blob维度为[1, 100, 3, 150],模型第一层卷积要求输入通道为3,但系统误把宽度100识别成了通道数。

常见问题解答:blobFromImage是唯一方式吗?

不是。blobFromImage只是OpenCV封装的图像预处理便捷接口,整合了resize、归一化、通道交换、维度调整等步骤。你完全可以手动完成所有预处理操作,只要最终输入给网络的四维张量维度、数值范围、通道顺序符合模型要求即可。

修复步骤

你需要按顺序修改代码中的两个核心错误:

  1. 修正归一化系数的整数运算问题
    你当前写的1/255是C++整数除法,运算结果直接为0,会导致整张图片的像素值被置为0,需要修改为浮点数除法1.0/255.0。
  2. 调整张量维度顺序匹配模型要求
    OpenCV的blobFromImage默认生成的是NCHW格式的四维张量(顺序为[batch数, 通道数, 高度, 宽度]),正常情况下你传入cv::Size(100,150)后生成的张量应该是[1,3,150,100],如果你的模型是用TensorFlow等框架训练、导出的ONNX默认是NHWC格式(顺序为[batch数, 高度, 宽度, 通道数]),你需要额外调用接口调整维度顺序。

修正后完整可运行代码

#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <vector>

int main() {
   std::vector< cv::Mat > outs;
   std::cout << "LOAD DNN in CPP Project!" << std::endl;
   cv::Mat image = cv::imread("example.png",1);
   if(image.empty()){
       std::cerr << "图像读取失败,请检查路径" << std::endl;
       return -1;
   }
   cv::dnn::Net net;
   net = cv::dnn::readNetFromONNX("model.onnx");
   if(net.empty()){
       std::cerr << "模型读取失败,请检查路径" << std::endl;
       return -1;
   }
   cv::Mat blob;
   // 修正归一化系数,根据模型要求调整swapRB参数
   cv::dnn::blobFromImage(image, blob, 1.0/255.0, cv::Size(100,150), cv::Scalar(0,0,0), false,false);
   // 调试用:打印blob维度确认是否符合要求
   // std::cout << "Blob shape: [" << blob.size[0] << ", " << blob.size[1] << ", " << blob.size[2] << ", " << blob.size[3] << "]" << std::endl;
   // 如果模型要求NHWC格式,取消下一行注释
   // blob = blob.permute({0, 2, 3, 1});
   net.setInput(blob);
   net.forward( outs, "output");
   return 0;
}

内容的提问来源于stack exchange,提问作者MH.AI.eAgLe

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 01:18:02