这是一个.NET/C#
的项目,我正在尝试使用Tensorflow.Net
通过Tensorflow
模型馈送图像。在我输入图像之前,它必须采用 4D 字节数组的形式,就像 numpy 数组或 Tensorflow.Net 所说的NDArray
一样。我有以下代码:
var bitmapBytes = GetBitmapBytes(testImage);
var imgArr = NumSharp.np.array(bitmapBytes);
但是当我通过 Tensorflow 模型运行 imgArr(NDArray 类型(时,我得到以下异常:
System.Exception: 'input 必须是 4-dimensional [1] [[{{node 预处理器/map/while/ResizeImage/ResizeBilinear}}]]'
作为记录,对GetBitmapBytes
方法的调用只是使用BitmapData
和锁位将位图转换为字节数组,因为我想要一定程度的性能。
因此,我能够成功地将位图转换为字节数组,该数组返回为具有适当长度的一维字节数组,以匹配我的图像 W x H。但是,我需要它是一个 4D 数组。
谢谢!
编辑:我们发布了NumSharp.Bitmap,它提供了对System.Drawing.Bitmap
的扩展
> Install-Package NumSharp.Bitmap
从位图:
using NumSharp;
//from bitmap
var ndarray = bitmap.ToNDArray(flat: false, copy: false);
//ndarray.shape == (1, height, width, 3).
到位图:
//to bitmap
var bitmap_from_ndarray = ndarray.ToBitmap(width, height);
//or
var bitmap_from_ndarray = ndarray.ToBitmap(ndarray.shape[1], ndarray.shape[2]);
原答:以下方法应该可以做到。
public static NDArray GetBitmapBytes(Bitmap image)
{
if (image == null) throw new ArgumentNullException(nameof(image));
BitmapData bmpData = image.LockBits(new Rectangle(0, 0, image.Width, image.Height), ImageLockMode.ReadOnly, image.PixelFormat);
try
{
unsafe
{
//Create a 1d vector without filling it's values to zero (similar to np.empty)
var nd = new NDArray(NPTypeCode.Byte, Shape.Vector(bmpData.Stride * image.Height), fillZeros: false);
// Get the respective addresses
byte* src = (byte*)bmpData.Scan0;
byte* dst = (byte*)nd.Unsafe.Address; //we can use unsafe because we just allocated that array and we know for sure it is contagious.
// Copy the RGB values into the array.
Buffer.MemoryCopy(src, dst, nd.size, nd.size); //faster than Marshal.Copy
return nd.reshape(1, image.Height, image.Width, 3);
}
}
finally
{
image.UnlockBits(bmpData);
}
}