0

我想在 UWP 应用程序中使用预训练的MobileNet,它期望像素范围为 0-1 的图像与 Windows ML。

问题是,ImageFeatureValue 只支持 0-255 的范围。

所以我需要更换 ImageFeatureValue ,它也可以调整图像大小,但能够使用像素范围 0-1。

在 GitHub 上找到了这种方法

{
    SoftwareBitmap bitmapBuffer = new SoftwareBitmap(BitmapPixelFormat.Bgra8, 224, 224, BitmapAlphaMode.Ignore))
    VideoFrame buffer = VideoFrame.CreateWithSoftwareBitmap(bitmapBuffer))
    await inputFrame.CopyToAsync(buffer);
    SoftwareBitmap resizedBitmap = buffer.SoftwareBitmap;
    WriteableBitmap innerBitmap = new WriteableBitmap(resizedBitmap.PixelWidth, resizedBitmap.PixelHeight);
    resizedBitmap.CopyToBuffer(innerBitmap.PixelBuffer);
    int[] pixels = innerBitmap.GetBitmapContext().Pixels;
    float[] array = NormalizeImage(pixels);
}

private float[] NormalizeImage(int[] src)
{
    var normalized = new float[src.Length * 3];
    for (int i = 0; i < src.Length; i++)
    {
        var val = src[i];
        normalized[i * 3 + 0] = (float)(val & 0xFF) / (float)255;
        normalized[i * 3 + 1] = (float)((val >> 8) & 0xFF) / (float)255;
        normalized[i * 3 + 2] = (float)((val >> 16) & 0xFF) / (float)255;
    }
    return normalized;
}

问题是 WritableBitmap 在 UWP 应用程序中不提供 GetBitmapContext().Pixels(仅在 .NET 中)。

我还没有找到另一种将 SoftwareBitmap / WritableBitmap 转换为像素数组的方法。

我怎么能做到这一点?

我认为,TensorFoat 可以像这样从数组中创建:

long[] shape = {1, 3, 224, 224};
TensorFloat tf = TensorFloat.CreateFromArray(shape, array);

这个对吗?

谢谢!

4

1 回答 1

1

检查 PixelBuffer文档作为 Nico 回答。按照示例将图像内容复制到 WriteableBitmap 的像素缓冲区。

// An array containing the decoded image data, which could be modified before being displayed 
byte[] sourcePixels = pixelData.DetachPixelData(); 

// Open a stream to copy the image contents to the WriteableBitmap's pixel buffer 
using (Stream stream = Scenario4WriteableBitmap.PixelBuffer.AsStream()) 
{ 
    await stream.WriteAsync(sourcePixels, 0, sourcePixels.Length); 
}

然后Normailze字节数组

for (UINT32 i = 0; i < size; i += 4)
{
    UINT32 pixelInd = i / 4;
    pFloatTensor[pixelInd] = (float)sourcePixels[i];
    pFloatTensor[(height * width) + pixelInd] = (float)sourcePixels[i + 1];
    pFloatTensor[(height * width * 2) + pixelInd] = (float)sourcePixels[i + 2];
}

最后,您将从该浮点数组创建一个 TensorFloat 变量并在评估之前绑定它(检查TensorFloat.CreateFromArray()

于 2021-01-21T22:10:11.543 回答