简体   繁体   English

如何在 C++ 中为 tensorflow-lite 设置带有图像的输入?

[英]How to set input with image for tensorflow-lite in c++?

I am trying to move our Tensoflow model from Python+Keras version to Tensorflow Lite with C++ on an embedded platform.我正在尝试在嵌入式平台上使用 C++ 将我们的 Tensoflow 模型从 Python+Keras 版本移动到 Tensorflow Lite。

It looks like I don't know how set properly input for interpreter.看起来我不知道如何为解释器正确设置输入。

Input shape should be (1, 224, 224, 3).输入形状应为 (1, 224, 224, 3)。

As an input I am taking image with openCV, converting this to CV_BGR2RGB.作为输入,我使用 openCV 拍摄图像,将其转换为 CV_BGR2RGB。


std::unique_ptr<tflite::FlatBufferModel> model_stage1 = 
tflite::FlatBufferModel::BuildFromFile("model1.tflite");
  TFLITE_MINIMAL_CHECK(model_stage1 != nullptr);

  // Build the interpreter
  tflite::ops::builtin::BuiltinOpResolver resolver_stage1;
  std::unique_ptr<Interpreter> interpreter_stage1;
  tflite::InterpreterBuilder(*model_stage1, resolver_stage1)(&interpreter_stage1);

TFLITE_MINIMAL_CHECK(interpreter_stage1 != nullptr);

  cv::Mat cvimg = cv::imread(imagefile);
  if(cvimg.data == NULL) {
    printf("=== IMAGE READ ERROR ===\n");
    return 0;
  }

  cv::cvtColor(cvimg, cvimg, CV_BGR2RGB);

  uchar* input_1 = interpreter_stage1->typed_input_tensor<uchar>(0);

 memcpy( ... );

I have issue with proper setup of memcpy for this uchar type.我在为这种 uchar 类型正确设置 memcpy 时遇到问题。

When I am doing like this, I have seg fault during working:当我这样做时,我在工作期间出现了段错误:

memcpy(input_1, cvimg.data, cvimg.total() * cvimg.elemSize());

How should I properly fill input in this case?在这种情况下,我应该如何正确填写输入?

To convert my comments into an answer: Memcpy might not be the right approach here.将我的评论转换为答案:Memcpy 在这里可能不是正确的方法。 OpenCV saves images as 1-dimensional arrays of RGB-ordered (or BGR or yet another color combination) color values per pixel. OpenCV 将图像保存为每像素 RGB 排序(或 BGR 或另一种颜色组合)颜色值的一维数组。 It is possible to iterate over these RGB-chunks via:可以通过以下方式迭代这些 RGB 块:

for (const auto& rgb : cvimg) {
    // now rgb[0] is the red value, rgb[1] green and rgb[2] blue.
}

And writing values to a Tensorflow-Lite typed_input_tensor should be done like this;将值写入 Tensorflow-Lite typed_input_tensor 应该像这样完成; where i is the index (iterator) and x the assigned value:其中 i 是索引(迭代器), x 是分配的值:

interpreter->typed_input_tensor<uchar>(0)[i] = x;

So the loop could look like this:所以循环看起来像这样:

for (size_t i = 0; size_t < cvimg.size(); ++i) {
    const auto& rgb = cvimg[i];
    interpreter->typed_input_tensor<uchar>(0)[3*i + 0] = rgb[0];
    interpreter->typed_input_tensor<uchar>(0)[3*i + 1] = rgb[1];
    interpreter->typed_input_tensor<uchar>(0)[3*i + 2] = rgb[2];
}

This is how you can do it at least for the single channel case.至少对于单通道情况,您可以这样做。 This assumes that the opencv bufffer is contiguous.这假设 opencv 缓冲区是连续的。 So, in this case, tensor dims are (1, x, y, 1).因此,在这种情况下,张量暗是 (1, x, y, 1)。

float* out = interpreter->typed_tensor<float>(input);
input_type = interpreter->tensor(input)->type;
img.convertTo(img, CV_32F, 255.f/input_std);
cv::subtract(img, cv::Scalar(input_mean/input_std), img);
float* in = img.ptr<float>(0);
memcpy(out, in, img.rows * img.cols * sizeof(float));

OpenCV version - 4.3.0 TF Lite version - 2.0.0 OpenCV 版本 - 4.3.0 TF Lite 版本 - 2.0.0

nada's approach is also correct. nada的做法也是正确的。 Pick whichever suits your programming style, however memcpy version is going to be comparatively faster.选择适合您的编程风格的任何一个,但是 memcpy 版本会相对更快。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM