For debugging purposes, I would like to have a 4D-CV Mat completely exported to an external file. I was thinking on numpy (npy/npz), hdf5 or zarr. Is that possible? Does someone have a code snipped which one can share?
(Background: the model.forward step of cv2.dnn results in a 4D CV Mat, where it is unclear to me how to slice the array)
if you are talking about python, net.forward() will result in a numpy array, you can simply use numpy.save()to serialize it
if it’s really c++, take a look at the tests, there’s npy code .
you could also use cv::FileStorage
tell us, what your network does. does it use some “known” architecture ?
Hello berak, thank you for the answer. I’ll try to explain my purpose and my approach.
The network does semantic segmentation with different output layers. Using the onnx-format I got (1,256,256,3) as output dimension (verified with python). As far as I understand the documentation it seems that NCHW is not supported at onnx as output layer.
For my working variant in C# (GitHub - shimat/opencvsharp: OpenCV wrapper for .NET) with protobuf,
I use the following with CvDnn.ReadNetFromTensorflow (output shape: 1, 3, 256, 256)
Mat[] layer = new Mat[2];
layer[0] = new Mat(256, 256, MatType.CV_32FC1, rawOutput.Ptr(0, 1));
layer[1] = new Mat(256, 256, MatType.CV_32FC1, rawOutput.Ptr(0, 2));
Now I want to switch to the onnx-format and access the different output layer.
Trying to convert the final CV Mat from hwc to chw and use the slicing above was not successful.
// Stretch one-channel images to vector
foreach (var img in channels)
{
img.Reshape(1, 1);
}
//// Concatenate three vectors to one
Cv2.HConcat(channels, dst);
return dst;
assuming, [1,3,256,256] means 3 color channels, i think, you wanted this instead (the opposite of that hwc_to_chw function :
Mat[] layer = new Mat[3];
layer[0] = new Mat(256, 256, MatType.CV_32FC1, rawOutput.Ptr(0, 0));
layer[1] = new Mat(256, 256, MatType.CV_32FC1, rawOutput.Ptr(0, 1));
layer[2] = new Mat(256, 256, MatType.CV_32FC1, rawOutput.Ptr(0, 2));
Mat res = new Mat;
Cv2.merge(layer, res); // res has "interleaved" channels
apart from that, a few questions:
“Using the onnx-format I got …” <–> “Now I want to switch to the onnx-format” – what, now ?
“As far as I understand the documentation it seems that NCHW is not supported at onnx as output layer.” – have a link ?
can you point us to some code / repo you’re trying to use ?
segmentation networks usually return masks (either a single channel labels mask, or a list of n per-class maps), – not color channels, what about it ?
Thank you very much for the answer. Probably my answer was a bit to unclear,
because I don’t think/understand cv2.merge might work.
For the NCHW-case ([1,3,256,256]) I’ve a C#-solution to get out
the correct slices of interest. In my case the first slice is only background.
Therefore I access slice 2 and 3 with
layer[1] = new Mat(256, 256, MatType.CV_32FC1, rawOutput.Ptr(0, 1));
layer[2] = new Mat(256, 256, MatType.CV_32FC1, rawOutput.Ptr(0, 2))
The output with Onnx is in the NWHC ([1,256,256,3]). Therefore my idea
was to change the cv mat to NCWH-case and then adresse again with
layer[1] = new Mat(256, 256, MatType.CV_32FC1, chwConverted.Ptr(0, 1));
layer[2] = new Mat(256, 256, MatType.CV_32FC1, chwConverted.Ptr(0, 2));
The current working implementation with C# works with old tensorflow <2.2 protobuf version. Newer tensorflow version lead to not out-of-the-box
working pb files
Unfortunalty, I cannot point to repo, but probably I’ve to share more code to reproduce.
In my case C are the per class maps. As I’ve only 3 output layer (one for the background, and two for the objects of interessant), I can colorcode my results.