cv::Mat是有多维的!!!!!
构造函数为:
/** @overload
@param ndims Array dimensionality.
@param sizes Array of integers specifying an n-dimensional array shape.
@param type Array type. Use CV_8UC1, ..., CV_64FC4 to create 1-4 channel matrices, or
CV_8UC(n), ..., CV_64FC(n) to create multi-channel (up to CV_CN_MAX channels) matrices.
*/
Mat(int ndims, const int* sizes, int type);
对于 tensor转mat
torch::Tensor out_des = torch::zeros(256,50,80) //[256,50,80]
int size[] = {256,50,80};
cv::Mat des(3, size, CV_32FC1, out_des.data_ptr<float>()); //3 dims
对于mat 转tensor
torch::Tensor des_tensor = torch::from_blob(des.data,{256,50,80},torch::kFloat32);
经过多次实际测试,我上面那种方式是错误的,原因是我没有考虑tensor和Mat的存放顺序是不同的。
tensor 是按照NCHW存放,而mat是按照HW*C存放,所以像上面那样直接转换是不对的!!下面这段代码是正确的转换。image.rows=400,cols=640,图像是单通道。
torch::Tensor img_tensor = torch::from_blob(image.data, {1, image.rows, image.cols, 1}, torch::kByte); //这时N*H*W*C
img_tensor = img_tensor.permute({0, 3, 1, 2}).to(device_); //转为N*C*H*W
img_tensor = img_tensor.to(torch::kFloat) / 255;
auto out = module_->forward({img_tensor}).toTuple(); //score descriptor
torch::Tensor out_des = out->elements()[1].toTensor().to(torch::kCPU); //1*256*50*80
//这里我没有使用高维的mat,去掉第一维后其实只有三维,把256当作通道(mat可最大使用512通道)即可实现三维,将其转为mat的存放格式,把256放到最后
torch::Tensor out_des1 = out_des.squeeze().detach().permute({1, 2, 0}); //去掉1,换为50*80*256
cv::Mat tmp_des(50, 80, CV_32FC(256), out_des1.data_ptr<float>()); //3 dims
torch::Tensor des_tensor = torch::from_blob(tmp_des.data,{1,50,80,256},torch::kFloat); //把mat再转回来 //1*50*80*256
des_tensor = des_tensor.permute({0, 3, 1, 2}).to(device_); //需要把C放在第二维 1*256*50*80
这样转的,des_tensor才等于out_des。
如果tensor只是两维则可以直接转。如果是更高维(>4),或者N>1,我也不知道怎么转,知道的麻烦教教我。