【发布时间】:2021-01-16 09:41:17
【问题描述】:
我正在使用 mediaframes (Kinect) 在 UWP 上实时获取颜色、深度/红外帧。这是为了将帧数据存储在磁盘上,然后再进行处理。
对于颜色,我使用 Memorystream 获取以字节为单位的像素。
// Get the Individual color Frame
var vidFrame = clrFrame?.VideoMediaFrame;
{
if (vidFrame == null) return;
// create a UWP SoftwareBitmap and copy Color Frame into Bitmap
SoftwareBitmap sbt = new SoftwareBitmap(vidFrame.SoftwareBitmap.BitmapPixelFormat, vidFrame.SoftwareBitmap.PixelWidth, vidFrame.SoftwareBitmap.PixelHeight);
vidFrame.SoftwareBitmap.CopyTo(sbt);
// PixelFormat needs to be in 8bit for Colour only
if (sbt.BitmapPixelFormat != BitmapPixelFormat.Bgra8)
sbt = SoftwareBitmap.Convert(vidFrame.SoftwareBitmap, BitmapPixelFormat.Bgra8);
if (source != null)
{
var ignore = Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, async () =>
{
extBitmap = new WriteableBitmap(sbt.PixelWidth, sbt.PixelHeight);
sbt.CopyToBuffer(extBitmap.PixelBuffer);
byte[] pixels = PixelBufferToWriteableBitmap(extBitmap);
extBitmap.Invalidate();
await SavePixelsToFile(pixels);
});
}
}
public async Task<byte[]> PixelBufferToWriteableBitmap(WriteableBitmap wb)
{
using (Stream stream = wb.PixelBuffer.AsStream())
{
using (MemoryStream memoryStream = new MemoryStream())
{
await stream.CopyToAsync(memoryStream);
byte[] pixels = memoryStream.ToArray();
return pixels;
}
}
}
红外像素格式为 Gray16(在 SoftwareBitmap 中);我想保留原始像素数据(因此帧中不会丢失任何数据)并将其写入 ushort[] 数组中的本地文件夹。
以下是链接,我遇到了如何从软件位图中获取设置像素。但是,它是bgra到字节,我想将软件位图转换为ushort。
How to set/get pixel from Softwarebitmap
https://docs.microsoft.com/en-us/windows/uwp/audio-video-camera/imaging
我是新手,不知道如何继续。
有人可以帮忙吗?
编辑
我认为可以通过执行以下操作将缓冲区媒体帧转换为字节数组:
公共异步任务
using (Stream stream = buffFrame.Buffer.AsStream())
{
using (MemoryStream memoryStream = new MemoryStream())
{
await stream.CopyToAsync(memoryStream);
byte[] pixels = memoryStream.ToArray();
return pixels;
}
}
}
但我不确定这样做是否会丢失红外帧的信息。由于红外和深度是每像素 16 位,并且当前的字节转换保持 8 bpp。对于这个 ushort[] 将能够保持 16bpp。 我对此很陌生,不确定所以我希望我做对了吗?
编辑 2:
我在 byte[] 中得到了像素数据。 我知道 byte 是 8 位,short 是 16 位,所以我更改了数组的长度:
int width = softwareBitmap.PixelWidth;
int height = softwareBitmap.PixelHeight;
int length = width * height * 2;
byte[] irbyteData = new byte[length]; // *2 to get 16 bit
var irshortData = new ushort[width * height]; // 16 bit ushort
IntPtr ptr = (IntPtr)pixelBytesAddress;
Marshal.Copy(ptr, irbyteData, 0, length); //seems to successfully get pixels from memory but not sure if this is lossless
【问题讨论】:
-
您的问题不清楚。您声明“像素格式为 Gray16” 并且您“想要保留原始像素数据”,但您发布的代码假定像素格式为 32 位RGBA。而且它甚至不读取缓冲区;它只是根据位图中像素的 X 值生成灰度渐变。您发布的代码以什么方式相关?与您想要发生的事情类似的实际代码在哪里?
-
帧到达时像素格式为 Gray16 但如何获取 ushort[] (16bit) 中的像素以将这些信息存储在磁盘上?
-
那么,你只是想将相同的 Gray16 帧作为图像存入磁盘吗?
-
是的,我想在不丢失任何信息的情况下将 Gray16 帧保存到磁盘。
标签: c# image image-processing uwp bitmap