OpenCV::dnn::readNet throwing exception

Viewed 449

I am following this tutorial to load the yolov5*.onnx models with the OpenCV DNN module and use it to make inference. I get the following error when trying to load the model:

[ERROR:0@10.376] global E:\Libraries\C++\opencv_gpu\opencv_source\modules\dnn\src\onnx\onnx_importer.cpp (1021) cv::dnn::dnn4_v20220524::ONNXImporter::handleNode DNN/ONNX: ERROR during processing node with 1 inputs and 1 outputs: [Identity]:(onnx_node!Identity_0) from domain='ai.onnx' OpenCV(4.6.0-dev)

E:\Libraries\C++\opencv_gpu\opencv_source\modules\dnn\src\onnx\onnx_importer.cpp:1040: error: (-2:Unspecified error) in function 'cv::dnn::dnn4_v20220524::ONNXImporter::handleNode' > Node [Identity@ai.onnx]:(onnx_node!Identity_0) parse error: OpenCV(4.6.0-dev) E:\Libraries\C++\opencv_gpu\opencv_source\modules\dnn\src\layer.cpp:246: error: (-215:Assertion failed) inputs.size() in function 'cv::dnn::dnn4_v20220524::Layer::getMemoryShapes' >

The minimal code to reproduce the error is as follows:

#include <iostream>
#include <fstream>

// openCV related includes
#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;
using namespace cv::dnn;
using namespace cuda;

int main()
{
    printCudaDeviceInfo(0);
    
    // Load model.
    Net net;
    try
    {
        //net = readNet("yolov5s.onnx");
        net = readNetFromONNX("yolov5s.onnx");
    }
    catch (cv::Exception& e)
    {
        cerr << endl << endl << e.msg << endl << endl; // output exception message
        return -1;
    }
    
    return 0
}

I built OpenCV from source with CUDA / CuDNN other relevant modules using cmake on windows. (OpenCV version 4.6.0).

Why I am getting this exception? How can I correctly load the onnx model of yolo?

2 Answers

Disclaimer: I have no experience using any of the listed technologies except for C++.

The last line of the error message you are seeing

E:\Libraries\C++\opencv_gpu\opencv_source\modules\dnn\src\layer.cpp:246: error: (-215:Assertion failed) inputs.size() in function 'cv::dnn::dnn4_v20220524::Layer::getMemoryShapes' >

failed an assertion that inputs.size() is non-zero. I think it may be due to you not setting inputs for your Net object. In the tutorial which you linked to, in section 4.3.4, they implement a helper function "pre_process", which takes an input image, converts it to a blob, and sets that as the input of the net. See section 4.3.6 for how/where they call pre_process in their main function. Are you following that part of the tutorial outside of the minimal reproducible example you provided?

I don't know anything about ONNX, so if your input is being set inside your ONNX file, please add the body of the file to your minimal reproducible example.

I used your good minimal example and reproduced the error with opencv 4.6.0 (build from source):

[ERROR:0] global ../modules/dnn/src/onnx/onnx_importer.cpp (1876) handleNode DNN/ONNX: ERROR during processing node with 1 inputs and 1 outputs: [Identity]:(onnx::Reshape_475)

I seems to be a version problem of either:

  1. opencv reading the onnx file (I was able to read an other onnx e.g. the restnet onnx file here without any trouble)
  2. the pip package of onnx v.1.12 is producing an file version (called for onnx 'opset version') which could not yet be handled by opencv

I haven't found the right combination ( and I tried some), but some people in the comment section of your mentioned article suggested to use opencv version 4.5.4.60

An alternative A) is to use an other format like TensorFlow GraphDef *.pb files The funtion cv::dnn::readNet suggests a lot more options:

*.caffemodel (Caffe, http://caffe.berkeleyvision.org/)
*.pb (TensorFlow, https://www.tensorflow.org/)
*.t7 | *.net (Torch, http://torch.ch/)
*.weights (Darknet, https://pjreddie.com/darknet/)
*.bin (DLDT, https://software.intel.com/openvino-toolkit)
*.onnx (ONNX, https://onnx.ai/)

The export.py script of the project yolov5 offers some options: Format | export.py --include | Model --- | --- | --- PyTorch | - | yolov5s.pt TorchScript | torchscript | yolov5s.torchscript ONNX | onnx | yolov5s.onnx OpenVINO | openvino | yolov5s_openvino_model/ TensorRT | engine | yolov5s.engine CoreML | coreml | yolov5s.mlmodel TensorFlow SavedModel | saved_model | yolov5s_saved_model/ TensorFlow GraphDef | pb | yolov5s.pb TensorFlow Lite | tflite | yolov5s.tflite TensorFlow Edge TPU | edgetpu | yolov5s_edgetpu.tflite TensorFlow.js | tfjs | yolov5s_web_model/

An alternative B) could be to use the pip package onnx to convert the file version. See the docu here.

Related