1

I want to deploy a trained deep neural network in c++ application. After reading image and using blobFromImage( I used opencv 4.4 ) function I received the blew error which is indicate I have problem with dimensions and shape of my tensor. The input of deep neural network is (h=150, w=100, channel=3). Is blobFromImage function the only way to make tensor? how can I fix this problem? Thanks in advance. I put my code and the error.

#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/*, cv::IMREAD_GRAYSCALE*/);

   cv::dnn::Net net;
   net = cv::dnn::readNetFromONNX("model.onnx");
   cv::Mat blob;

   cv::dnn::blobFromImage(image, blob, 1/255, cv::Size(100,150), cv::Scalar(0,0,0), false,false);
   net.setInput(blob);
   net.forward( outs, "output");

   return 0;
 }

and the error is:

global /home/hasa/opencv4.4/opencv-4.4.0/modules/dnn/src/dnn.cpp (3441) getLayerShapesRecursively OPENCV/DNN: [Convolution]:(model/vgg19/block1_conv1/BiasAdd:0):  getMemoryShapes() throws exception. inputs=1 outputs=0/1 blobs=2
[ERROR:0] global /home/hasa/opencv4.4/opencv-4.4.0/modules/dnn/src/dnn.cpp (3447) getLayerShapesRecursively     input[0] = [ 1 100 3 150 ]
[ERROR:0] global /home/hasa/opencv4.4/opencv-4.4.0/modules/dnn/src/dnn.cpp (3455) getLayerShapesRecursively     blobs[0] = CV_32FC1 [ 64 3 3 3 ]
[ERROR:0] global /home/hasa/opencv4.4/opencv-4.4.0/modules/dnn/src/dnn.cpp (3455) getLayerShapesRecursively     blobs[1] = CV_32FC1 [ 64 1 ]
[ERROR:0] global /home/hasa/opencv4.4/opencv-4.4.0/modules/dnn/src/dnn.cpp (3457) getLayerShapesRecursively Exception message: OpenCV(4.4.0) /home/hasa/opencv4.4/opencv- 4.4.0/modules/dnn/src/layers/convolution_layer.cpp:346: error: (-2:Unspecified error)  Number of input channels should be multiple of 3 but got 100 in function  'getMemoryShapes'

terminate called after throwing an instance of 'cv::Exception'
what(): OpenCV(4.4.0) /home/hasa/opencv4.4/opencv-  4.4.0/modules/dnn/src/layers/convolution_layer.cpp:346: error:  (-2:Unspecified error) Number of input channels should be multiple of  3 but got 100 in function 'getMemoryShapes'


Process finished with exit code 134 (interrupted by signal 6: SIGABRT)
MH.AI.eAgLe
  • 592
  • 1
  • 6
  • 22
  • Can you please answer https://stackoverflow.com/questions/69633595/load-onnx-model-in-opencv-dnn?noredirect=1#comment123084665_69633595 as net = cv::dnn::readNetFromONNX("model.onnx"); works for you. – fisakhan Oct 21 '21 at 12:17

1 Answers1

-1

Using .onnx model needs some changes.

The following code works for me if I load tensorflow model.

inputNet = cv::dnn::readNetFromTensorflow(pbFilePath);
// load image of rowsxcols = 100x150
cv::Mat img, imgn, blob;
img = cv::imread("1.jpg");
//cv::cvtColor(img, img, CV_GRAY2RGB);// convert gray to color image
    
// normalize image (if needed)
//img.convertTo(imgn, CV_32FC3);//float32, 3channels (depends on your model)
//imgn = (imgn-127.5)/128.0;//normalized crop (in rgb)
    
//extract feature vector
cv::dnn::blobFromImage(imgn, blob, 1.0, cv::Size(100, 150),0, false, false);
inputNet.setInput(blob);
cv::Mat feature_vector = inputNet.forward();

If I load .onnx model then I need to change the dimensions like this:

std::cout << blob.size << std::endl;// NCHW
blob = blob.reshape(1, {1, 100,150, 3});// NHWC
std::cout << blob.size << std::endl;
inputNet.setInput(blob);
fisakhan
  • 704
  • 1
  • 9
  • 27