【问题标题】:Convert vector<Tensor> outputs To vector<Mat> outputs将 vector<Tensor> 输出转换为 vector<Mat> 输出
【发布时间】: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;

}

【问题讨论】:

    标签: c++ tensorflow


    【解决方案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::Tensor的tensor&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]; 超出范围访问)

    【讨论】:

    • 谢谢你的回答,我试试这个
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-12-07
    • 1970-01-01
    • 2012-04-19
    • 1970-01-01
    • 1970-01-01
    • 2014-05-16
    • 1970-01-01
    相关资源
    最近更新 更多