如何从 EmguCV 中的 YUV_420_888 字节数组创建 Image 或 Mat 实例?
How to create a Image or Mat instance from a YUV_420_888 byte array in EmguCV?
问题:
我从 android 设备接收一个 YUV_420_888 图像作为字节缓冲区(简单地连接图像平面缓冲区)。我知道图像的尺寸,我需要将它显示到我的 GUI 上。
我目前有:
目前我只能使用具有以下功能的灰度 Y 平面:
private BitmapImage GetImageFromBuffer(byte[] imgBuffer)
{
Image<Gray, byte> emguImg = new Image<Gray, byte>(1280, 720);
emguImg.Bytes = imgBuffer;
var img = new BitmapImage();
using (MemoryStream ms = new MemoryStream(emguImg.ToJpegData()))
{
img.BeginInit();
img.CacheOption = BitmapCacheOption.OnLoad;
img.CreateOptions = BitmapCreateOptions.PreservePixelFormat;
img.StreamSource = ms;
img.EndInit();
}
return img;
}
我也测试了类似的代码,使用 Image.ToBitmap()
函数并将中间位图复制到内存流,作为 BitmapImage
的源。
无论如何,我想从传入的 byte[]
创建一个 BitmapSource
的 BitmapImage
(或我可以用来在 GUI 上显示的任何类型)。
据我所知,我必须从字节数组创建一个 Mat
实例,将其转换为 RGB,然后将其保存为可显示格式。
下面的代码似乎可以解决问题:
private BitmapImage GetImageFromBuffer(byte[] imgBuffer)
{
unsafe
{
fixed (byte* p = imgBuffer)
{
IntPtr ptr = (IntPtr)p;
Mat yuvMat = new Mat(1080, 1280, Emgu.CV.CvEnum.DepthType.Cv8U, 1, ptr, 1280);
Mat rgbMat = new Mat();
CvInvoke.CvtColor(yuvMat, rgbMat, Emgu.CV.CvEnum.ColorConversion.Yuv420Sp2Rgb);
var img = new BitmapImage();
using (MemoryStream ms = new MemoryStream())
{
img.BeginInit();
rgbMat.Bitmap.Save(ms, ImageFormat.Bmp);
img.CacheOption = BitmapCacheOption.OnLoad;
img.CreateOptions = BitmapCreateOptions.PreservePixelFormat;
img.StreamSource = ms;
img.EndInit();
}
return img;
}
}
}
也许有人可以确认,如果这是要走的路或评论改进建议。
问题: 我从 android 设备接收一个 YUV_420_888 图像作为字节缓冲区(简单地连接图像平面缓冲区)。我知道图像的尺寸,我需要将它显示到我的 GUI 上。
我目前有: 目前我只能使用具有以下功能的灰度 Y 平面:
private BitmapImage GetImageFromBuffer(byte[] imgBuffer)
{
Image<Gray, byte> emguImg = new Image<Gray, byte>(1280, 720);
emguImg.Bytes = imgBuffer;
var img = new BitmapImage();
using (MemoryStream ms = new MemoryStream(emguImg.ToJpegData()))
{
img.BeginInit();
img.CacheOption = BitmapCacheOption.OnLoad;
img.CreateOptions = BitmapCreateOptions.PreservePixelFormat;
img.StreamSource = ms;
img.EndInit();
}
return img;
}
我也测试了类似的代码,使用 Image.ToBitmap()
函数并将中间位图复制到内存流,作为 BitmapImage
的源。
无论如何,我想从传入的 byte[]
创建一个 BitmapSource
的 BitmapImage
(或我可以用来在 GUI 上显示的任何类型)。
据我所知,我必须从字节数组创建一个 Mat
实例,将其转换为 RGB,然后将其保存为可显示格式。
下面的代码似乎可以解决问题:
private BitmapImage GetImageFromBuffer(byte[] imgBuffer)
{
unsafe
{
fixed (byte* p = imgBuffer)
{
IntPtr ptr = (IntPtr)p;
Mat yuvMat = new Mat(1080, 1280, Emgu.CV.CvEnum.DepthType.Cv8U, 1, ptr, 1280);
Mat rgbMat = new Mat();
CvInvoke.CvtColor(yuvMat, rgbMat, Emgu.CV.CvEnum.ColorConversion.Yuv420Sp2Rgb);
var img = new BitmapImage();
using (MemoryStream ms = new MemoryStream())
{
img.BeginInit();
rgbMat.Bitmap.Save(ms, ImageFormat.Bmp);
img.CacheOption = BitmapCacheOption.OnLoad;
img.CreateOptions = BitmapCreateOptions.PreservePixelFormat;
img.StreamSource = ms;
img.EndInit();
}
return img;
}
}
}
也许有人可以确认,如果这是要走的路或评论改进建议。