我正在使用Kinect 2.0,尤其是颜色流。色彩流以1920×1080的分辨率到达,非常棒!除此之外,我打算捕获图像字节并将其写入磁盘。因此,对我来说最可行的解决方案是压缩每个图像帧,然后存储压缩图像而不是原始高分辨率图像。
我有一个解决方案,但我觉得它有点像“围绕房子”这样做的方式。
基本上,我得到原始像素,将它们写入WriteableBitmap,然后使用以下两种方法压缩ImageSource:
1)写入WriteableBitmap:
this.colorBitmap.WritePixels(
new Int32Rect(0, 0, this.colorBitmap.PixelWidth, this.colorBitmap.PixelHeight),
this.colorPixels,
this.colorBitmap.PixelWidth * (int)this.bytesPerPixel,
0);
2)将其压缩为jpeg:
public static byte[] CompressToBytes(ImageSource src, int compressionrate)
{
var enc = new JpegBitmapEncoder();
enc.QualityLevel = compressionrate;
var bf = BitmapFrame.Create((BitmapSource)src);
enc.Frames.Add(bf);
using (var ms = new MemoryStream())
{
enc.Save(ms);
return ms.ToArray();
}
}
正如我所说,哪个工作正常,但我认为如果我能从Kinect获取原始像素然后直接压缩字节数组而不是写入WriteableBitmap然后压缩它会更好。这似乎是一个额外的步骤。
BTW,这是我用来从彩色帧中获取字节的代码:
using (ColorFrame colorFrame = e.FrameReference.AcquireFrame())
{
if (colorFrame != null)
{
FrameDescription colorFrameDescription = colorFrame.FrameDescription;
if ((colorFrameDescription.Width == this.colorBitmap.PixelWidth) && (colorFrameDescription.Height == this.colorBitmap.PixelHeight))
{
if (colorFrame.RawColorImageFormat == ColorImageFormat.Bgra)
{
colorFrame.CopyRawFrameDataToArray(this.colorPixels);
}
else
{
colorFrame.CopyConvertedFrameDataToArray(this.colorPixels, ColorImageFormat.Bgra);
}
}
}
}
请记住,当以每秒所有帧数处理颜色流时,您可以捕获掉落(大概从30-32到26-29),我想使用最有效的方法。
有一件事我注意到在c#中搜索压缩解决方案时,很多文章都是针对将单个映像存储到磁盘上的。虽然我需要在内存中执行此压缩,因为我正在将多个图像写入磁盘(使用二进制编写器)。