# Model inference resulting in unknown rows and cols

**URL:** <https://forum.opencv.org/t/model-inference-resulting-in-unknown-rows-and-cols/14251>\
**Category:** C++\
**Tags:** dnn\
**Created:** [August 14, 2023, 2:54pm UTC](https://forum.opencv.org/t/model-inference-resulting-in-unknown-rows-and-cols/14251 "2023-08-14T14:54:52Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![mentejoao](https://avatars.discourse-cdn.com/v4/letter/m/a9a28c/32.png) [@mentejoao](https://forum.opencv.org/u/mentejoao)\
**Post date:** [August 14, 2023, 2:54pm UTC](https://forum.opencv.org/t/model-inference-resulting-in-unknown-rows-and-cols/14251/1 "2023-08-14T14:54:52Z")

</div>

I converted a Tensorflow Model to ONNX and then load it using OpenCV DNN. This model expects a [-1, 100, 100, 1] input and gives a [-1, 100, 100 ,1] output

 ![digs](https://us1.discourse-cdn.com/flex020/uploads/opencv/original/2X/5/567fe9e3392d90b49ac5e752006b0a4d252b4fdc.png)

I tested in Python, creating a dummy input and I got exactly what I expected, a 100x100 output.

```auto
...
params = cv2.dnn.Image2BlobParams()
params.mean = (0,0,0)
params.scalefactor = (1,1,1)
params.size = (100, 100)
params.ddepth = cv2.CV_32F
params.datalayout = cv2.dnn.DNN_LAYOUT_NHWC
params.paddingmode = cv2.dnn.DNN_PMODE_NULL
...
batch_size = 1
h = 100
w = 100
c = 1
x = torch.rand(batch_size, h, w, c, requires_grad=False)
x_npy = x.detach().numpy()
x_opencv = x_npy.reshape(h, w, 1)

blobPB = cv2.dnn.blobFromImageWithParams(x_opencv, params)
modelopenCV.setInput(blobPB)
output = modelopenCV.forward()
print(output.shape) # = (1, 100, 100, 1)

```

But I’m having issue in acessing my output elements in C++, my cv::Mat output from model.foward() gets -1 rows and -1 cols. Any idea of how can I acess this elements? Why this difference between Python and C++ result? I know that OpenCV Python uses np.arrays instead of cv::Mat for data storage, but I guess it should has the same dimensions of a cv::Mat, using a input with the correct dimensions and the same model… no?

```auto
...
		params.scalefactor = 1.0 / 255;
		params.size = cv::Size2i::Size_(100, 100);
		params.mean = 0.0;
		params.ddepth = CV_32F;
		params.datalayout = cv::dnn::DNN_LAYOUT_NHWC;
		params.paddingmode = cv::dnn::DNN_PMODE_NULL;
        cv::dnn::blobFromImageWithParams(imgpb, blobTest, params);
        /* trust me imgpb it's in correct dimensions, imgpb.rows = 100, imgpb.cols = 100, imgpb.channels() = 1 */
		pModelONNXPeB.setInput(blobTest);
	    cv::Mat outputsPB1 = pModelONNXPeB.forward();

```

outputsPB1 has 4 dimensions, -1 rows and -1 cols

---

<div class="post-metadata">

**Author:** ![berak](https://avatars.discourse-cdn.com/v4/letter/b/85f322/32.png) [@berak](https://forum.opencv.org/u/berak)\
**Post date:** [August 14, 2023, 3:10pm UTC](https://forum.opencv.org/t/model-inference-resulting-in-unknown-rows-and-cols/14251/2 "2023-08-14T15:10:57Z")

</div>

> [@mentejoao](#):
>
> outputsPB1 has 4 dimensions, -1 rows and -1 cols

opencv sets rows & cols to -1 for more-than-2-dim Mats.  
please use `outputsPB1.size` (w/o braces !) in the same way you would use `xxx.shape` in python

---

<div class="post-metadata">

**Author:** ![mentejoao](https://avatars.discourse-cdn.com/v4/letter/m/a9a28c/32.png) [@mentejoao](https://forum.opencv.org/u/mentejoao)\
**Post date:** [August 14, 2023, 3:18pm UTC](https://forum.opencv.org/t/model-inference-resulting-in-unknown-rows-and-cols/14251/3 "2023-08-14T15:18:58Z")

</div>

Didn’t know that… thanks, Berak. Could you give me an example of the syntax for acessing an element in 4 dim struct? I’m used to

```auto
	for (int i = 0; i < outputsPB1.rows; ++i) {
					for (int j = 0; j < outputsPB1.cols; ++j) {
						float valor = outputsPB1.at<float>(i, j);

```

But as you said, -1 rols and -1 cols are setted for \> 2 dims, I can’t use this in this case.

---

<div class="post-metadata">

**Author:** ![berak](https://avatars.discourse-cdn.com/v4/letter/b/85f322/32.png) [@berak](https://forum.opencv.org/u/berak)\
**Post date:** [August 14, 2023, 3:25pm UTC](https://forum.opencv.org/t/model-inference-resulting-in-unknown-rows-and-cols/14251/4 "2023-08-14T15:25:18Z")

</div>

you can use `at<float>(i,j,k)` , iterate over `outputsPB1.shape[0]`(batch dim) etc.

but in your case, you probably want to make a simple [100,100] 2d Mat from it:

```
Mat res2d(100, 100, CV_32F, outputsPB1.ptr<float>(0)); // batch item 0

```

---

<div class="post-metadata">

**Author:** ![laurent.berger](https://avatars.discourse-cdn.com/v4/letter/l/ec9cab/32.png) [@laurent.berger](https://forum.opencv.org/u/laurent.berger)\
**Post date:** [August 14, 2023, 4:00pm UTC](https://forum.opencv.org/t/model-inference-resulting-in-unknown-rows-and-cols/14251/5 "2023-08-14T16:00:42Z")

</div>

> [@mentejoao](#):
>
> ould you give me an example of the syntax for acessing an element in 4 dim struct

May be you can try this

```auto
/**
* return a specific Mat in a blob.
* if dims blob is less or equal to 2 (N rows x M columns) blob is return
* if dims blob is 3 blob is blob is (H x N x M array) mat at (coord(0),0, 0) is returned.
* if dims blob is r blob is blob is (T x H x N x M array) mat at (coord(0), coord(1), 0, 0) is returned.
* */
Mat getMatInBlob(Mat blob, vector<int> coord, int posChannel = DNN_LAYOUT_NCHW)
{
 }

```

---

<div class="post-metadata">

**Author:** ![laurent.berger](https://avatars.discourse-cdn.com/v4/letter/l/ec9cab/32.png) [@laurent.berger](https://forum.opencv.org/u/laurent.berger)\
**Post date:** [August 14, 2023, 4:03pm UTC](https://forum.opencv.org/t/model-inference-resulting-in-unknown-rows-and-cols/14251/6 "2023-08-14T16:03:36Z")

</div>

> [@mentejoao](#):
>
> `modelopenCV.setInput(blobPB)`

here you should try

`modelopenCV.setInput(cv.Mat(blobPB))`

> <https://github.com/opencv/opencv/issues/18880#issuecomment-917093130>
>
> I'm trying to convert a model that is trained on PyTorch to an onnx model and us…e it in a C++ application. For this, as an initial step, I'm saving and evaluating the model directly in Python. However I get the following assertion error with the minimal example code below:
> 
> \`\`\` 
> \[ERROR:0\] global C:\\Users\\appveyor\\AppData\\Local\\Temp\\1\\pip-req-build-6sxsq0tp\\opencv\\modules\\dnn\\src\\dnn.cpp (3444) cv::dnn::dnn4\_v20200609::Net::Impl::getLayerShapesRecursively OPENCV/DNN: \[LSTM\]:(36/lstm): getMemoryShapes() throws exception. inputs=1 outputs=0/1 blobs=3
> \[ERROR:0\] global C:\\Users\\appveyor\\AppData\\Local\\Temp\\1\\pip-req-build-6sxsq0tp\\opencv\\modules\\dnn\\src\\dnn.cpp (3447) cv::dnn::dnn4\_v20200609::Net::Impl::getLayerShapesRecursively input\[0\] = \[5 3 \]
> \[ERROR:0\] global C:\\Users\\appveyor\\AppData\\Local\\Temp\\1\\pip-req-build-6sxsq0tp\\opencv\\modules\\dnn\\src\\dnn.cpp (3455) cv::dnn::dnn4\_v20200609::Net::Impl::getLayerShapesRecursively blobs\[0\] = CV\_32FC1 \[80 20 \]
> \[ERROR:0\] global C:\\Users\\appveyor\\AppData\\Local\\Temp\\1\\pip-req-build-6sxsq0tp\\opencv\\modules\\dnn\\src\\dnn.cpp (3455) cv::dnn::dnn4\_v20200609::Net::Impl::getLayerShapesRecursively blobs\[1\] = CV\_32FC1 \[80 10 \]
> \[ERROR:0\] global C:\\Users\\appveyor\\AppData\\Local\\Temp\\1\\pip-req-build-6sxsq0tp\\opencv\\modules\\dnn\\src\\dnn.cpp (3455) cv::dnn::dnn4\_v20200609::Net::Impl::getLayerShapesRecursively blobs\[2\] = CV\_32FC1 \[1 80 \]
> \[ERROR:0\] global C:\\Users\\appveyor\\AppData\\Local\\Temp\\1\\pip-req-build-6sxsq0tp\\opencv\\modules\\dnn\\src\\dnn.cpp (3457) cv::dnn::dnn4\_v20200609::Net::Impl::getLayerShapesRecursively Exception message: OpenCV(4.4.0) C:\\Users\\appveyor\\AppData\\Local\\Temp\\1\\pip-req-build-6sxsq0tp\\opencv\\modules\\dnn\\src\\layers\\recurrent\_layers.cpp:201: error: (-215:Assertion failed) inp0.size() \>= 2 && total(inp0, 2) == \_numInp in function 'cv::dnn::LSTMLayerImpl::getMemoryShapes'
> Traceback (most recent call last):
> File ".\\onnx-lstm.py", line 53, in \<module\>
> out = net.forward()
> cv2.error: OpenCV(4.4.0) C:\\Users\\appveyor\\AppData\\Local\\Temp\\1\\pip-req-build-6sxsq0tp\\opencv\\modules\\dnn\\src\\layers\\recurrent\_layers.cpp:201: error: (-215:Assertion failed) inp0.size() \>= 2 && total(inp0, 2) == \_numInp in function 'cv::dnn::LSTMLayerImpl::getMemoryShapes'
> \`\`\`
> 
> \`\`\`
> import cv2
> import torch
> import numpy as np
> 
> rnn = torch.nn.LSTM(10, 20, 1)
> dummy\_input = torch.randn(5, 3, 10)
> dummy\_h0 = torch.randn(1, 3, 20)
> dummy\_c0 = torch.randn(1, 3, 20)
> output, (hn, cn) = rnn(dummy\_input, (dummy\_h0, dummy\_c0))
> torch.onnx.export(rnn, dummy\_input, "lstm.onnx", verbose=True)
> 
> net = cv2.dnn.readNet("lstm.onnx")
> inp = np.zeros((5, 3, 10))
> net.setInput(inp)
> out = net.forward()
> \`\`\`
> 
> What would be the way to resolve this error?
> 
> \##### System information (version)
> \- OpenCV = 4.4
> \- Operating System / Platform =\> Windows 64 Bit
> 
> Onnx model link: \[lstm.zip\](https://github.com/opencv/opencv/files/5575263/lstm.zip)

---

<div class="post-metadata">

**Author:** ![mentejoao](https://avatars.discourse-cdn.com/v4/letter/m/a9a28c/32.png) [@mentejoao](https://forum.opencv.org/u/mentejoao)\
**Post date:** [August 14, 2023, 5:06pm UTC](https://forum.opencv.org/t/model-inference-resulting-in-unknown-rows-and-cols/14251/7 "2023-08-14T17:06:35Z")

</div>

Really good! A generic implementation, I will save for later, thanks for the tip. I don’t know, if I can reutilize this topic for another question, but in this same context of 4d data structs, is there anyway to pass a 4d data to a blob? blobFromImages only accepts structs with dims \<= 2, right? I got this 4 dimension output and I need to create a blob from it to pass as input for another model.

---

<div class="post-metadata">

**Author:** ![laurent.berger](https://avatars.discourse-cdn.com/v4/letter/l/ec9cab/32.png) [@laurent.berger](https://forum.opencv.org/u/laurent.berger)\
**Post date:** [August 14, 2023, 7:04pm UTC](https://forum.opencv.org/t/model-inference-resulting-in-unknown-rows-and-cols/14251/8 "2023-08-14T19:04:30Z")

</div>

> [@mentejoao](#):
>
> I got this 4 dimension output and I need to create a blob from it to pass as input for another model.

A blob is a Mat  
So you can do :

```auto
  Mat maskInput(vector<int> {1, 1, 256, 256}, CV_32FC1);
  netMask.setInput(maskInput, "mask_input");

```
