【问题标题】:How to transform Byte[](decoded as PNG or JPG) to Tensorflows Tensor如何将 Byte[](解码为 PNG 或 JPG)转换为 Tensorflows 张量
【发布时间】:2018-06-15 12:11:38
【问题描述】:

我正在尝试在 Unity 的项目中使用 Tensorflowsharp。

我面临的问题是,对于转换,您通常使用第二个 Graph 将输入转换为张量。 Android 不支持使用的函数 DecodeJpg 和 DecodePng 那么如何将该输入转换为张量?

private static void ConstructGraphToNormalizeImage(out TFGraph graph, out TFOutput input, out TFOutput output, TFDataType destinationDataType = TFDataType.Float)
{

    const int W = 224;
    const int H = 224;
    const float Mean = 117;
    const float Scale = 1;
    graph = new TFGraph();
    input = graph.Placeholder(TFDataType.String);
    output = graph.Cast(graph.Div(
        x: graph.Sub(
            x: graph.ResizeBilinear(
                images: graph.ExpandDims(
                    input: graph.Cast(
                        graph.DecodeJpeg(contents: input, channels: 3), DstT: TFDataType.Float),
                    dim: graph.Const(0, "make_batch")),
                size: graph.Const(new int[] { W, H }, "size")),
            y: graph.Const(Mean, "mean")),
        y: graph.Const(Scale, "scale")), destinationDataType);
}

其他解决方案似乎会产生不准确的结果。

也许有一个 Mat 对象?

和我的编辑: 我在 Unity 的 c# 中实现了一些类似的东西,它可以部分工作。它根本不准确。我要如何找出平均值?而且我找不到有关 rgb 顺序的任何信息。?我对此真的很陌生,所以也许我只是忽略了它。 (在 Tensorflow.org 上)使用在 1.4 中训练的 MobileNet。

  public TFTensor transformInput(Color32[] pic, int texturewidth, int textureheight)
    {
        const int W = 224;
        const int H = 224;
        const float imageMean = 128;
        const float imageStd = 128;

        float[] floatValues = new float[texturewidth * textureheight * 3];

        for (int i = 0; i < pic.Length; ++i)
        {
            var color = pic[i];
            var index = i * 3;

            floatValues[index] = (color.r - imageMean) / imageStd;
            floatValues[index + 1] = (color.g - imageMean) / imageStd;
            floatValues[index + 2] = (color.b - imageMean) / imageStd;

        }
        TFShape shape = new TFShape(1, W, H, 3);
        return TFTensor.FromBuffer(shape, floatValues, 0, floatValues.Length);
    }

【问题讨论】:

  • 您好,您能提供更多关于网络的信息吗?你是自己训练的还是使用预训练的网络?我在 tensorflow.org 上没有看到任何预训练的 MobilNets。
  • 这是一个经过再训练的网络,使用他们的脚本与花本质上(更多的图片和“无”类别来否定 FP)。在 Python 中,这件事就像一个魅力。当我使用该脚本在 c# 中测试相同的图片时,它是不准确的(在 python 之外的任何脚本中都不准确)。它具有 1.0 224 架构。所有 TensorFlow 实例似乎都是 1.4 的某个版本。

标签: c# android opencv tensorflow tensorflowsharp


【解决方案1】:

您可能没有在将图像放入@sladomic 函数之前对其进行裁剪和缩放。

我设法拼凑了一个sample of using TensorflowSharp in Unity 用于对象分类。它适用于官方 Tensorflow Android 示例中的模型,也适用于我自训练的 MobileNet 模型。您只需要替换模型并设置均值和标准差,在我的情况下它们都等于 224。

【讨论】:

  • 谢谢会调查的。我(后来)基本上以 NN 所需的分辨率剪掉了图片的中间部分。但这仍然不准确。我会调查你做了什么谢谢。如果我找到时间,我会用我发现的内容更新我的问题,也许它适用于你当时所做的事情。
【解决方案2】:

您可以输入实际的浮点数组,而不是输入字节数组,然后使用 DecodeJpeg,您可以像这样得到:

https://github.com/tensorflow/tensorflow/blob/3f4662e7ca8724f760db4a5ea6e241c99e66e588/tensorflow/examples/android/src/org/tensorflow/demo/TensorFlowImageClassifier.java#L134

float[] floatValues = new float[inputSize * inputSize * 3];
int[] intValues = new int[inputSize * inputSize];

bitmap.getPixels(intValues, 0, bitmap.getWidth(), 0, 0, bitmap.getWidth(), bitmap.getHeight());
for (int i = 0; i < intValues.length; ++i) {
      final int val = intValues[i];
      floatValues[i * 3 + 0] = (((val >> 16) & 0xFF) - imageMean) / imageStd;
      floatValues[i * 3 + 1] = (((val >> 8) & 0xFF) - imageMean) / imageStd;
      floatValues[i * 3 + 2] = ((val & 0xFF) - imageMean) / imageStd;
}

Tensor<Float> input = Tensors.create(floatValues);

要使用“Tensors.create()”,您需要至少拥有 Tensorflow 1.4 版。

【讨论】:

  • 首先感谢您的回答。我实现了一些类似的东西,但该图几乎可以预测任何没有真正准确性的东西。这是一个 MobilNet,我可能只需要找出我需要的平均值和标准吗?
  • 天哪,我在使用 decodejpeg 时遇到了很多问题,我不敢相信手动加载它是如此简单。非常感谢!!
猜你喜欢
  • 2015-01-31
  • 2021-10-14
  • 1970-01-01
  • 1970-01-01
  • 2012-09-15
  • 2012-04-09
  • 1970-01-01
  • 2019-04-13
  • 1970-01-01
相关资源
最近更新 更多