Backends/SiaNet.Backend.TensorSharp/Cuda/BitmapExtensions.cs
/// <summary>
/// Returns a Tensor constructed from the data in the Bitmap. The Tensor's dimensions are
/// ordered CHW (channel x height x width). The color channel dimension is in the same order
/// as the original Bitmap data. For 24bit bitmaps, this will be BGR. For 32bit bitmaps this
/// will be BGRA.
/// </summary>
/// <param name="bitmap">The bitmap.</param>
/// <param name="allocator">The allocator.</param>
/// <returns>Tensor.</returns>
/// <exception cref="InvalidOperationException">Bitmap must be 24bit or 32bit</exception>
Returns a Tensor constructed from the data in the Bitmap. The Tensor's dimensions are
ordered CHW (channel x height x width). The color channel dimension is in the same order
as the original Bitmap data. For 24bit bitmaps, this will be BGR. For 32bit bitmaps this
will be BGRA.
Returns a Tensor constructed from the data in the Bitmap . The Tensor ' s dimensions are ordered CHW ( channel x height x width ) . The color channel dimension is in the same order as the original Bitmap data . For 24bit bitmaps this will be BGR . For 32bit bitmaps this will be BGRA .
public static NDArray ToTensor(this Bitmap bitmap, IAllocator allocator)
        {
            var cpuAllocator = new Cpu.CpuAllocator();
            int bytesPerPixel = 0;
            if (bitmap.PixelFormat == PixelFormat.Format24bppRgb)
                bytesPerPixel = 3;
            else if (bitmap.PixelFormat == PixelFormat.Format32bppArgb ||
                bitmap.PixelFormat == PixelFormat.Format32bppPArgb ||
                bitmap.PixelFormat == PixelFormat.Format32bppRgb)
                bytesPerPixel = 4;
            else
                throw new InvalidOperationException("Bitmap must be 24bit or 32bit");
            var lockData = bitmap.LockBits(
                new Rectangle(0, 0, bitmap.Width, bitmap.Height),
                ImageLockMode.ReadOnly,
                bitmap.PixelFormat);
            try
            {
                var sizes = new long[] { bitmap.Height, bitmap.Width, bytesPerPixel };
                var strides = new long[] { lockData.Stride, bytesPerPixel, 1 };
                using (var cpuByteTensor = new NDArray(cpuAllocator, DType.UInt8, sizes, strides))
                {
                    cpuByteTensor.Storage.CopyToStorage(cpuByteTensor.StorageOffset, lockData.Scan0, cpuByteTensor.Storage.ByteLength);
                    using (var permutedTensor = cpuByteTensor.Transpose(2, 0, 1))
                    {
                        using (var cpuFloatTensor = new NDArray(cpuAllocator, DType.Float32, permutedTensor.Shape))
                        {
                            Ops.Copy(cpuFloatTensor, permutedTensor);
                            var result = new NDArray(allocator, DType.Float32, permutedTensor.Shape);
                            Ops.Copy(result, cpuFloatTensor);
                            Ops.Div(result, result, 255);
                            return result;
                        }
                    }
                }
            }
            finally
            {
                bitmap.UnlockBits(lockData);
            }
        }
public static NDArray ToTensor ( this Bitmap bitmap , IAllocator allocator ) { var cpuAllocator = new Cpu . CpuAllocator ( ) ; int bytesPerPixel = 0 ; if ( bitmap . PixelFormat == PixelFormat . Format24bppRgb ) bytesPerPixel = 3 ; else if ( bitmap . PixelFormat == PixelFormat . Format32bppArgb || bitmap . PixelFormat == PixelFormat . Format32bppPArgb || bitmap . PixelFormat == PixelFormat . Format32bppRgb ) bytesPerPixel = 4 ; else throw new InvalidOperationException ( " " ) ; var lockData = bitmap . LockBits ( new Rectangle ( 0 , 0 , bitmap . Width , bitmap . Height ) , ImageLockMode . ReadOnly , bitmap . PixelFormat ) ; try { var sizes = new long [ ] { bitmap . Height , bitmap . Width , bytesPerPixel } ; var strides = new long [ ] { lockData . Stride , bytesPerPixel , 1 } ; using ( var cpuByteTensor = new NDArray ( cpuAllocator , DType . UInt8 , sizes , strides ) ) { cpuByteTensor . Storage . CopyToStorage ( cpuByteTensor . StorageOffset , lockData . Scan0 , cpuByteTensor . Storage . ByteLength ) ; using ( var permutedTensor = cpuByteTensor . Transpose ( 2 , 0 , 1 ) ) { using ( var cpuFloatTensor = new NDArray ( cpuAllocator , DType . Float32 , permutedTensor . Shape ) ) { Ops . Copy ( cpuFloatTensor , permutedTensor ) ; var result = new NDArray ( allocator , DType . Float32 , permutedTensor . Shape ) ; Ops . Copy ( result , cpuFloatTensor ) ; Ops . Div ( result , result , 255 ) ; return result ; } } } } finally { bitmap . UnlockBits ( lockData ) ; } }
Returns a Tensor constructed from the data in the Bitmap.
Returns a Tensor constructed from the data in the Bitmap .
// TODO this could be made more efficient by skipping a the following copy if allocator is a CpuAllocator, // but make sure that in that case the result tensor is not disposed before returning.
None
Bitmap must be 24bit or 32bit
Bitmap must be 24bit or 32bit
Bitmap
this
<not_specific>
allocator
IAllocator
None
bitmap
<not_specific>
None