如何将 Byte[](解码为 PNG 或 JPG)转换为 Tensorflows Tensor
How to transform Byte[](decoded as PNG or JPG) to Tensorflows Tensor
我正在尝试在 Unity 的项目中使用 Tensorflowsharp。
我面临的问题是,对于转换,您通常使用第二个图形将输入转换为张量。
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# 实现了一些 comparabel,它部分工作。它根本不准确。我怎样才能找出均值?我找不到任何关于 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);
}
您可以提供实际的浮点数组,而不是先提供字节数组然后使用 DecodeJpeg,您可以像这样得到它:
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。
在将图像放入@sladomic 函数之前,您可能没有裁剪和缩放图像。
我设法组合了一个 sample of using TensorflowSharp in Unity 用于对象分类。它适用于来自官方 Tensorflow Android 示例的模型,也适用于我自训练的 MobileNet 模型。您只需要更换模型并设置您的均值和标准差,在我的情况下均等于 224。
我正在尝试在 Unity 的项目中使用 Tensorflowsharp。
我面临的问题是,对于转换,您通常使用第二个图形将输入转换为张量。 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# 实现了一些 comparabel,它部分工作。它根本不准确。我怎样才能找出均值?我找不到任何关于 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);
}
您可以提供实际的浮点数组,而不是先提供字节数组然后使用 DecodeJpeg,您可以像这样得到它:
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。
在将图像放入@sladomic 函数之前,您可能没有裁剪和缩放图像。
我设法组合了一个 sample of using TensorflowSharp in Unity 用于对象分类。它适用于来自官方 Tensorflow Android 示例的模型,也适用于我自训练的 MobileNet 模型。您只需要更换模型并设置您的均值和标准差,在我的情况下均等于 224。