在Tensorflow C ++中,我可以使用
将图像文件加载到图形中tensorflow::Node* file_reader = tensorflow::ops::ReadFile(tensorflow::ops::Const(IMAGE_FILE_NAME, b.opts()),b.opts().WithName(input_name));
tensorflow::Node* image_reader = tensorflow::ops::DecodePng(file_reader, b.opts().WithAttr("channels", 3).WithName("png_reader"));
tensorflow::Node* float_caster = tensorflow::ops::Cast(image_reader, tensorflow::DT_FLOAT, b.opts().WithName("float_caster"));
tensorflow::Node* dims_expander = tensorflow::ops::ExpandDims(float_caster, tensorflow::ops::Const(0, b.opts()), b.opts());
tensorflow::Node* resized = tensorflow::ops::ResizeBilinear(dims_expander, tensorflow::ops::Const({input_height, input_width},b.opts().WithName("size")),b.opts());
对于嵌入式应用程序,我想将OpenCV Mat传递给此图。
如何将Mat转换为可用作tensorflow :: ops :: Cast或tensorflow :: ops :: ExpandDims的输入的张量?
答案 0 :(得分:23)
它不是直接来自CvMat,但您可以在TensorFlow Android示例中看到如何从内存数组初始化Tensor的示例: https://github.com/tensorflow/tensorflow/blob/0.6.0/tensorflow/examples/android/jni/tensorflow_jni.cc#L173
你可以从创建一个新的tensorflow :: Tensor对象开始,使用类似的东西(所有代码都未经测试):
tensorflow::Tensor input_tensor(tensorflow::DT_FLOAT,
tensorflow::TensorShape({1, height, width, depth}));
这将创建一个具有浮点值的Tensor对象,批量大小为1,大小为width
x height
,并且带有depth
个通道。例如,具有3个通道的128宽×64高图像将以{1, 64, 128, 3}
的形状通过。批量大小仅在您需要在一次调用中传入多个图像时使用,对于简单用途,您可以将其保留为1。
然后你会使用这样的一行得到张量后面的底层数组:
auto input_tensor_mapped = input_tensor.tensor<float, 4>();
input_tensor_mapped
对象是新创建的张量中数据的接口,然后您可以将自己的数据复制到其中。在这里,我假设您已将source_data
设置为指向源数据的指针,例如:
const float* source_data = some_structure.imageData;
然后,您可以遍历数据并将其复制:
for (int y = 0; y < height; ++y) {
const float* source_row = source_data + (y * width * depth);
for (int x = 0; x < width; ++x) {
const float* source_pixel = source_row + (x * depth);
for (int c = 0; c < depth; ++c) {
const float* source_value = source_pixel + c;
input_tensor_mapped(0, y, x, c) = *source_value;
}
}
}
有很好的机会可以优化这种天真的方法,而且我手边没有示例代码来展示如何处理获取源数据的OpenCV方面,但希望这对您有所帮助。
答案 1 :(得分:1)
我曾尝试在opencv Mat
文件上运行启动模型,并且以下代码为我工作https://gist.github.com/kyrs/9adf86366e9e4f04addb。虽然opencv和tensorflow的集成存在一些问题。代码对.png
个文件没有任何问题,但无法加载.jpg
和.jpeg
。您可以按照此处获取更多信息https://github.com/tensorflow/tensorflow/issues/1924
答案 2 :(得分:0)
这里是阅读和供稿的完整示例:
Mat image;
image = imread("flowers.jpg", CV_LOAD_IMAGE_COLOR);
cv::resize(image, image, cv::Size(input_height, input_width), 0, 0, CV_INTER_CUBIC);
int depth = 3;
tensorflow::Tensor input_tensor(tensorflow::DT_FLOAT,
tensorflow::TensorShape({1, image.rows, image.cols, depth}));
for (int y = 0; y < image.rows; y++) {
for (int x = 0; x < image.cols; x++) {
Vec3b pixel = image.at<Vec3b>(y, x);
input_tensor_mapped(0, y, x, 0) = pixel.val[2]; //R
input_tensor_mapped(0, y, x, 1) = pixel.val[1]; //G
input_tensor_mapped(0, y, x, 2) = pixel.val[0]; //B
}
}
auto result = Sub(root.WithOpName("subtract_mean"), input_tensor, {input_mean});
ClientSession session(root);
TF_CHECK_OK(session.Run({result}, out_tensors));
答案 3 :(得分:0)
Tensor convertMatToTensor(Mat &input)
{
int height = input.rows;
int width = input.cols;
int depth = input.channels();
Tensor imgTensor(tensorflow::DT_FLOAT, tensorflow::TensorShape({height, width, depth}));
float* p = imgTensor.flat<float>().data();
Mat outputImg(height, width, CV_32FC3, p);
input.convertTo(outputImg, CV_32FC3);
return imgTensor;
}