在OpenCV C++中加载预训练ONNX模型失败求助
问题重现
加载模型的代码:
robustNN = cv::dnn::readNetFromONNX(robustNNPath);
报错信息:
[ERROR:0@0.460] global onnx_importer.cpp:1054 cv::dnn::dnn4_v20221220::ONNXImporter::handleNode DNN/ONNX: ERROR during processing node with 3 inputs and 1 outputs: [Concat]:(onnx_node!Concat_2) from domain='ai.onnx'
OpenCV: terminate handler is called! The last OpenCV error is:
OpenCV(4.7.0-dev) Error: Unspecified error (> Node [Concat@ai.onnx]:(onnx_node!Concat_2) parse error: OpenCV(4.7.0-dev) C:\GHA-OCV-2_work\ci-gha-workflow\ci-gha-workflow\opencv\modules\dnn\src\layers\concat_layer.cpp:105: error: (-215:Assertion failed) curShape.size() == outputs[0].size() in function 'cv::dnn::ConcatLayerImpl::getMemoryShapes'
) in cv::dnn::dnn4_v20221220::ONNXImporter::handleNode, file C:\GHA-OCV-2_work\ci-gha-workflow\ci-gha-workflow\opencv\modules\dnn\src\onnx\onnx_importer.cpp, line 1073
解决建议
- 升级OpenCV版本:你当前使用的4.7.0-dev开发版存在ONNX算子兼容性缺陷,建议升级到4.8.0及以上稳定版本,后续版本修复了大量ONNX模型导入的bug,尤其是Concat层的多维度拼接兼容问题。
- 改用ONNX Runtime加载模型:如果升级OpenCV后问题仍存在,可以直接用ONNX Runtime加载模型,该框架对标准ONNX格式的支持更完善。C++示例代码如下:
#include <onnxruntime_cxx_api.h> Ort::Env env(ORT_LOGGING_LEVEL_WARNING, "RobustVideoMatting"); Ort::SessionOptions session_options; session_options.SetIntraOpNumThreads(1); session_options.SetGraphOptimizationLevel(GraphOptimizationLevel::ORT_ENABLE_BASIC); Ort::Session session(env, robustNNPath.c_str(), session_options); - 显式指定模型输入维度:RobustVideoMatting模型要求特定输入维度(如默认1x3x1080x1920),OpenCV DNN若无法自动推断张量维度,会导致Concat层拼接时形状不匹配。可尝试加载后显式设置输入参数:
robustNN = cv::dnn::readNetFromONNX(robustNNPath); robustNN.setInputSize(cv::Size(1920, 1080)); robustNN.setInputScale(1.0 / 255.0); robustNN.setInputMean(cv::Scalar(0, 0, 0)); robustNN.setInputSwapRB(true);
内容的提问来源于stack exchange,提问作者Frank Escobar

