• libtorch之cv::Mat和Tensor的互转


          cv::Mat转Tensro libtorch官网例子中给的是如下形式:

            torch::TensorOptions option(torch::kFloat);   

            auto img_tensor = torch::from_blob(img.data,

                                                                 {1,img.rows,img.cols,img.channels() }, option);

                                                                // opencv (H x W x C)  to torch  (batch x H x W x C)

            img_tensor = img_tensor.permute({0, 3, 1, 2 });//调整矩阵列顺序 batch x C x H x W

         这种方式应用在分类问题中应该没什么问题,但应用在faster RCNN时却存在一定问题。使用from_blob构造一个Tensor,他只是一个内存数据的拷贝,没有更多的对数据处理。

          cv::Mat数据在内存中是如下形式存储的

         (r,g,b),(r,g,b),(r,g,b)......   

         然而Tensor在内存中的数据确是

          (r,r,r,r,......),(g,g,g,g,......),(b,b,b,......)

         这两种不同结构的数据是无法直接使用内存拷贝方式转换。

         以下是一个完整的cv::Mat转Tensor

        torch::Tensor image2Tensor(cv::Mat &img)

       {

              if(img.channels() == 1)

             {

                 torch::TensorOptions option(torch::kFloat);

                 auto img_tensor = torch::from_blob(img.data, {1,img.rows,img.cols}, option);

                                                                // opencv (H x W)  to torch  (C x H x W)

                  return img_tensor;

            }

           else

           {

                    torch::Tensor t = torch::zeros({3,img.rows,img.cols},torch::kFloat);

                   float * r = (float*)t[0].data_ptr();

                   float * g = (float*)t[1].data_ptr();

                   float * b = (float*)t[2].data_ptr();

                  for(int row = 0; row < img.rows; row++)

                 {

                         for(int col = 0; col < img.cols; col++)

                        {

                                cv::Vec3f &v = img.at(row,col);

                                r[row*img.cols + col] = v[0];

                                g[row*img.cols + col] = v[1];

                                b[row*img.cols + col] = v[2];

                       }

               }

                return t;

            }

             return torch::Tensor();

        }

         这是一个Tensor转cv::Mat的函数,方便可视化的呈现特征图像。

         cv::Mat tensor2Image(const torch::Tensor &t)

        {

                 torch::IntArrayRef s = t.sizes();

                 if(s[0] == 1)

                {

                        cv::Mat des(s[1], s[2], CV_32FC1, t.data_ptr());

                          return des;

                 }

                else

               {

                     float * r = (float*)t[0].data_ptr();

                     float * g = (float*)t[1].data_ptr();

                     float * b = (float*)t[2].data_ptr();

                     int rows = s[1];

                     int cols = s[2];

                     cv::Mat des = cv::Mat::zeros(rows, cols,CV_32FC3);

                    for(int row=0; row

                    {

                            for(int col=0; col

                           {

                                cv::Vec3f v;

                                v[0] = r[row*cols + col];

                                v[1] = g[row*cols + col];

                                v[2] = b[row*cols + col];

                               des.at(row,col) = v;

                           }

                    }

                   return des;

              }

              return cv::Mat();

          }

  • 相关阅读:
    I 用c I 实现队列
    特斯拉陷入巨大质疑:车祸前1秒,Autopilot自动退出
    Git与IDEA: 解决`dev`分支切换问题及其背后原因 为何在IDEA中无法切换到`dev`分支?全面解析!
    【linux】shell编程 脚本语法
    【luogu AT2382】A or...or B Problem(思维)
    pip 指定源
    基于神经网络彩色图像插值研究-附Matlab程序
    HTML是指什么 HTML的基本工作原理
    基于javaweb的在线美食分享推荐系统(java+ssm+jsp+jquery+mysql)
    【力扣每日一题01】两数之和
  • 原文地址:https://blog.csdn.net/wolfseek/article/details/133362780