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

如何向OpenCV DNN输入多类型异构模型输入(含不同尺寸图像与数组)

问题解决:OpenCV加载多输入TensorFlow模型报错处理

问题描述

加载TensorFlow的.pb模型,模型包含4类输入:

  • 256×256的图像
  • 两个64×64的图像
  • 长度为4的数组
    输出为长度2的数组。尝试将所有输入转成blob后放入vector,调用net.setInput()传入vector再执行forward()时触发断言错误:

libc++abi: terminating with uncaught exception of type cv::Exception: OpenCV(4.5.5) /tmp/opencv-20220714-27380-1eyun69/opencv-4.5.5/modules/core/src/matrix_wrap.cpp:81: error: (-215:Assertion failed) 0 <= i && i < (int)v.size() in function 'getMat_'

原尝试代码:

cv::dnn::Net net = cv::dnn::readNetFromTensorflow("model/mfg.pb");
cv::Mat input_face = cv::dnn::blobFromImage(face, 1, cv::Size(256,256), cv::Scalar(104,177,123), true, false);
cv::Mat input_leye = cv::dnn::blobFromImage(leye, 1, cv::Size(64,64), cv::Scalar(104,177,123), true, false);
cv::Mat input_reye = cv::dnn::blobFromImage(reye, 1, cv::Size(64,64), cv::Scalar(104,177,123), true, false);
cv::Mat input_bbox = (cv::Mat1d(1,4) << face_bbox[0], face_bbox[1], face_bbox[2], face_bbox[3]);

std::vector<cv::Mat> input_image = {input_face, input_leye, input_reye, input_bbox};
net.setInput(input_image);
net.forward();

错误原因

  1. 未绑定输入节点名称:直接传入vector的方式无法确保输入与模型定义的输入节点一一对应,模型可能找不到匹配的输入,导致索引越界。
  2. 第四个输入格式不匹配:模型大概率要求输入为float32类型,但代码中用Mat1d创建了double类型的矩阵;同时输入维度不符合模型要求(图像输入是[1,3,H,W]的blob格式,数组输入也需要保持类似的批量维度,即[1,4])。

解决方案

步骤1:获取模型输入节点名称

先通过OpenCV获取模型所有输入节点的名称,确保后续绑定正确:

// 打印所有输入节点的名称和形状
auto inputs = net.getInputs();
for (auto &input : inputs) {
    std::cout << "Input name: " << input.name() << ", shape: " << input.size() << std::endl;
}

运行这段代码可以得到每个输入节点的准确名称,比如可能是input_face、input_leye、input_reye、input_bbox这类命名。

步骤2:逐个设置输入并匹配名称

不要用vector批量传入,而是调用net.setInput(blob, inputName)逐个绑定输入,同时修正第四个输入的格式:

cv::dnn::Net net = cv::dnn::readNetFromTensorflow("model/mfg.pb");

// 处理图像输入,保持原blob转换逻辑
cv::Mat input_face = cv::dnn::blobFromImage(face, 1, cv::Size(256,256), cv::Scalar(104,177,123), true, false);
cv::Mat input_leye = cv::dnn::blobFromImage(leye, 1, cv::Size(64,64), cv::Scalar(104,177,123), true, false);
cv::Mat input_reye = cv::dnn::blobFromImage(reye, 1, cv::Size(64,64), cv::Scalar(104,177,123), true, false);

// 修正bbox输入:转成float32类型,生成[1,4]的blob格式
cv::Mat bbox_mat(1, 4, CV_32F);
float* bbox_data = bbox_mat.ptr<float>();
bbox_data[0] = face_bbox[0];
bbox_data[1] = face_bbox[1];
bbox_data[2] = face_bbox[2];
bbox_data[3] = face_bbox[3];
cv::Mat input_bbox = cv::dnn::blobFromImage(bbox_mat, 1.0, cv::Size(), cv::Scalar(), false, false);

// 用步骤1获取的实际输入名称绑定每个输入
net.setInput(input_face, "input_face");
net.setInput(input_leye, "input_leye");
net.setInput(input_reye, "input_reye");
net.setInput(input_bbox, "input_bbox");

// 执行推理并提取结果
cv::Mat output = net.forward();
float* output_data = output.ptr<float>();
std::cout << "Output: [" << output_data[0] << ", " << output_data[1] << "]" << std::endl;

关键注意事项

  • 输入名称必须和模型定义的完全一致,包括大小写、下划线等,否则模型无法识别输入。
  • 所有输入的数据类型必须匹配模型要求,大部分TensorFlow模型默认使用float32,避免用double类型。
  • 输入维度要符合模型要求:图像输入是[batch_size, channels, height, width],数组输入一般是[batch_size, feature_size],确保批量维度(第一个维度)存在。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 20:03:30