将内存位图图像转换为 4 维数组,如 numpy



这是一个.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);
}
}

最新更新