如何将 Mat 重塑为张量以在 C++ 中的深度神经网络中使用?

Posted

技术标签:

【中文标题】如何将 Mat 重塑为张量以在 C++ 中的深度神经网络中使用?【英文标题】:How can I reshape a Mat to a tensor to use in deep neural network in c++? 【发布时间】:2021-11-24 15:05:53 【问题描述】:

我想在 C++ 应用程序中部署经过训练的深度神经网络。在读取图像并使用 blobFromImage(我使用 opencv 4.4)函数后,我收到了自爆错误,这表明我的张量的尺寸和形状有问题。深度神经网络的输入为(h=150, w=100, channel=3)。 blobFromImage 函数是制作张量的唯一方法吗?我该如何解决这个问题?提前致谢。 我把我的代码和错误。

#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;
 

错误是:

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)

【问题讨论】:

您能否回答***.com/questions/69633595/… as net = cv::dnn::readNetFromONNX("model.onnx");适合你。 【参考方案1】:

以下代码对我有用。唯一的区别是我正在加载 tensorflow 模型。

inputNet = cv::dnn::readNetFromTensorflow(pbFilePath);
// load image of rowsxcols = 160x160
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(160, 160),0, false, false);
inputNet.setInput(blob);
cv::Mat feature_vector = inputNet.forward();

【讨论】:

这没有回答问题(这是关于奇怪和不常见的(H、W、C)输入格式) (H,W,C) 格式是老生常谈***.com/questions/52187913/…

以上是关于如何将 Mat 重塑为张量以在 C++ 中的深度神经网络中使用?的主要内容,如果未能解决你的问题,请参考以下文章

Tensorflowjs - 将 4d 张量重塑/切片成图像

如何将从 C++ 发送的 cv::MAT 字节数组转换为 Java 中的位图?

Pytorch 重塑张量维度

AI 新技术革命将如何重塑就业和全球化格局?深度解读 UN 报告 (下篇)

如何将 opencv Mat 类型传递给 Python 并返回一个数组?

重塑 pandas.Df 以在 GridSearch 中使用