为什么要搞这个?
书到用时方恨少,钱到月底不够花。我们上github搜索关键字,限定语言,你会发现没有C#这个选项... 不行,别人有的我们也要有!
资源有限,人脉有限。有幸得高人指点,充分利用C#语言的多维数组,让排列正确实现的同时又保证了代码的优雅性和可读性。
欢迎白嫖🍦!
参考文献和代码
代码
- using
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.PixelFormats;
using System.Runtime.InteropServices;
- 图像转NHWC -- 三维矩阵
public static ReadOnlySpan<byte> ImageToNHWC(Image<Rgb24> image)
{
var hwc = new byte[image.Height, image.Width, 3];
for (int h = 0; h < image.Height; h++)
{
for (int w = 0; w < image.Width; w++)
{
var px = image[w, h];
hwc[h, w, 0] = px.R;
hwc[h, w, 1] = px.G;
hwc[h, w, 2] = px.B;
}
}
return MemoryMarshal.CreateReadOnlySpan(ref hwc[0, 0, 0], 3 * image.Height * image.Width);
}
- 图像转NCHW -- 三维矩阵
public static ReadOnlySpan<byte> ImageToNCHW(Image<Rgb24> image)
{
var chw = new byte[3, image.Height, image.Width];
for (int w = 0; w < image.Width; w++)
{
for (int h = 0; h < image.Height; h++)
{
var px = image[w, h];
chw[0, h, w] = px.R;
chw[1, h, w] = px.G;
chw[2, h, w] = px.B;
}
}
return MemoryMarshal.CreateReadOnlySpan(ref chw[0, 0, 0], 3 * image.Height * image.Width);
}
- NHWC转NCHW -- 三维矩阵
public static ReadOnlySpan<byte> NHWCToNCHW(ReadOnlySpan<byte> bytes, int width, int height)
{
var chw = new byte[3, height, width];
for (int c = 0; c < 3; c++)
{
for (int h = 0; h < height; h++)
{
for (int w = 0; w < width; w++)
{
chw[c, h, w] = bytes[(h * width + w) * 3 + c];
}
}
}
return MemoryMarshal.CreateReadOnlySpan(ref chw[0, 0, 0], 3 * height * width);
}
- NCHW转NHWC -- 三维矩阵
public static ReadOnlySpan<byte> NCHWToNHWC(ReadOnlySpan<byte> bytes, int width, int height)
{
var hwc = new byte[height, width, 3];
for (int c = 0; c < 3; c++)
{
for (int h = 0; h < height; h++)
{
for (int w = 0; w < width; w++)
{
hwc[h, w, c] = bytes[(c * height + h) * width + w];
}
}
}
return MemoryMarshal.CreateReadOnlySpan(ref hwc[0, 0, 0], 3 * height * width);
}
- NCHW转图像 -- 数组切片
public static Image<Rgb24> NCHWToImage(ReadOnlySpan<byte> bytes, int width, int height)
{
var length = width * height;
var rChannel = bytes.Slice(0, length);
var gChannel = bytes.Slice(1 * length, length);
var bChannel = bytes.Slice(2 * length, length);
var image = new Image<Rgb24>(width, height);
for (int h = 0; h < height; h++)
{
for (int w = 0; w < width; w++)
{
var r = rChannel[h * width + w];
var g = gChannel[h * width + w];
var b = bChannel[h * width + w];
image[w, h] = new Rgb24(r, g, b);
}
}
return image ;
}
- NHWC转图像 -- 每三个字节一组,顺序填充到像素
public static Image<Rgb24> NHWCToImage(ReadOnlySpan<byte> bytes, int width, int height)
{
var image = new Image<Rgb24>(width, height);
for (int h = 0; h < height; h++)
{
for (int w = 0; w < width; w++)
{
var r = bytes[(h * width + w) * 3 + 0];
var g = bytes[(h * width + w) * 3 + 1];
var b = bytes[(h * width + w) * 3 + 2];
image[w, h] = new Rgb24(r, g, b);
}
}
return image;
}