简体   繁体   English

如何从 EmguCV 中的 YUV_420_888 字节数组创建 Image 或 Mat 实例?

[英]How to create a Image or Mat instance from a YUV_420_888 byte array in EmguCV?

The problem: I receive a YUV_420_888 image from an android device as a byte buffer (simply concatenated the image plane buffers).问题:我从 android 设备接收 YUV_420_888 图像作为字节缓冲区(简单地连接图像平面缓冲区)。 I know the dimension of the image and I need to display it onto my GUI.我知道图像的尺寸,我需要将它显示到我的 GUI 上。

What I have so far: At the moment I can use only the grayscale Y-plane with the following function:到目前为止我所拥有的:目前我只能使用带有以下 function 的灰度 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;
}

I also have tested a similar code, using Image.ToBitmap() function and copying the intermediate Bitmap to the memory stream, which serves as source for the BitmapImage . I also have tested a similar code, using Image.ToBitmap() function and copying the intermediate Bitmap to the memory stream, which serves as source for the BitmapImage . Anyway, I would like to create a BitmapImage of BitmapSource (or any type I can use to display on the GUI) from the incoming byte[] .无论如何,我想从传入的byte[]创建BitmapSourceBitmapImage (或我可以用来在 GUI 上显示的任何类型)。 As far as I could read up on it, I have to create a Mat instance from the byte array, convert it to RGB and then save it to a diplay-able format.据我所知,我必须从字节数组创建一个Mat实例,将其转换为 RGB,然后将其保存为可显示的格式。

The following code seems to do the trick:以下代码似乎可以解决问题:

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;
        }
    }
}

Maybe someone can confirm, if this is the way to go or comment suggestions for improvements.也许有人可以确认,如果这是 go 的方式或评论改进建议。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM