将 vector<Tensor> 输出转换为 vector<Mat> 输出

Posted

技术标签:

【中文标题】将 vector<Tensor> 输出转换为 vector<Mat> 输出【英文标题】:Convert vector<Tensor> outputs To vector<Mat> outputs 【发布时间】:2022-01-02 02:17:35 【问题描述】:

为 TensorFlow .PB 编写推理代码。

我正在尝试将std::vector&lt;Tensor&gt; outputs; 转换为vector&lt;Mat&gt;&amp; outputs;

我的张量输出形状是Tensor&lt;type: float shape: [16900,13] values: [4.09118605 1.63703501 6.61954...]...&gt;

代码

int main(int argc, char *argv[])


  string image = "image/june_2021_wfh3735.jpg";
  string graph = "model/6_nov10.pb";
  string labels = "model/classes.txt";
  int32 input_width = 416;
  int32 input_height = 416;
  float input_mean = 0;
  float input_std = 255;
  string input_layer = "input/input_data";
  vector<string> output_layer = "predict/concat", "lane/concat/concat" ;

  bool self_test = false;
  string root_dir = "";

  // First we load and initialize the model.
  std::unique_ptr<tensorflow::Session> session;
  string graph_path = tensorflow::io::JoinPath(root_dir, graph);

  LOG(ERROR) << "graph_path:" << graph_path;
  Status load_graph_status = LoadGraph(graph_path, &session);
  if (!load_graph_status.ok()) 
    LOG(ERROR) << "LoadGraph ERROR!!!!"<< load_graph_status;
    return -1;
  

  // Get the image from disk as a float array of numbers, resized and normalized
  // to the specifications the main graph expects.
  std::vector<Tensor> resized_tensors;
  string image_path = tensorflow::io::JoinPath(root_dir, image);
  Status read_tensor_status =
      ReadTensorFromImageFile(image_path, input_height, input_width, input_mean,
                              input_std, &resized_tensors);
  if (!read_tensor_status.ok()) 
    LOG(ERROR) << read_tensor_status;
    return -1;
  
  const Tensor& resized_tensor = resized_tensors[0];

  LOG(ERROR) <<"image shape:" << resized_tensor.shape().DebugString()<< ",len:" << resized_tensors.size() << ",tensor type:"<< resized_tensor.dtype();

  std::vector<Tensor> outputs;
  Status run_status = session->Run(input_layer, resized_tensor,
                                   output_layer, , &outputs);

  auto height = resized_tensor.shape().dim_sizes()[1];
  auto width = resized_tensor.shape().dim_sizes()[2];

  if (!run_status.ok()) 
    LOG(ERROR) << "Running model failed: " << run_status;
    return -1;
  

  std::cout << " " << outputs[0].shape().DebugString() << std::endl;
  return 0;


【问题讨论】:

【参考方案1】:

要获取tensorflow::Tensor 存储的数据,您可以:

[1] 使用返回void*Tensor::data() 方法。张量中的数据按行主要顺序存储,因此对于 2D 张量,您可以编写:

float* data = static_cast<float*>(tensor.data());
int width = ...; // read here second dim of tensor
auto accessData = [&](int y, int x) 
    return data[y * width + x];
;
cv::Mat m(height,width,CV_32FC1);
for (int y = 0; y < height; ++y)
    for (int x = 0; x < width; ++x)
        m.at<float>(y,x) = accessData(y,x);

[2] 使用tensorflow::Tensortensor&lt;T,NDIMS&gt;()模板方法获取data()指针的封装,提供operator()(Indices...)操作符,简化数据访问:

auto tensorMap = tensor.tensor<float,2>();
for (int y = 0; y < height; ++y)
   for (int x = 0; x < width; ++x)
      m.at<float>(y,x) = tensorMap(y,x);

'type: float shape: [16900,13]' 张量具有 2 维的索引,因此 resized_tensor.shape().dim_sizes()[2]; 超出范围访问)

【讨论】:

谢谢你的回答,我试试这个

以上是关于将 vector<Tensor> 输出转换为 vector<Mat> 输出的主要内容,如果未能解决你的问题,请参考以下文章

将 std::vector<std::tuple<>> 转换为 torch::Tensor 的最有效方法是啥?

C++中用vector存放一个数组,对数组进行排序,并输出数组

output_tensor 的 dlib 致命错误

关于将vector元素复制到数组

包装 Eigen::Vector 类型

张量(Tensor)标量(scalar)向量(vector)矩阵(matrix)