torch::tensor与cv::Mat相互转换

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,我也不知道怎么转,知道的麻烦教教我。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值