簡體   English   中英

將張量輸出轉換為 cv::mat

[英]Convert tensor outputs to cv::mat

為 TensorFlow .PB編寫推理代碼。

我正在嘗試轉換std::vector<Tensor> outputs; vector<Mat>& outputs;

而我的張量 output 形狀是Tensor<type: float shape: [16900,13] values: [4.09118605 1.63703501 6.61954...]...>

代碼

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;

}

要獲取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<T,NDIMS>()模板方法獲取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-dims,因此resized_tensor.shape().dim_sizes()[2];超出范圍訪問)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM