Search code examples
opencvpointersstreamunmanagedemgucv

How to efficiently get stream from EmguCV (OpenCV) image


I have an EmguCV.Image<Brg, Byte>() instance and another 3rd party API, that requires Stream that represents the image data.

I was able to convert the EmguCV image to the stream and pass it to the 3rd party API using System.Drawing.Bitmap.Save but that is not very efficient.

How to get the stream as afficietnly as possible?

This code works:

var image = new Image<Rgb, byte>("photo.jpg");
var bitmap = image.Bitmap// System.Drawing - this takes 108ms!
using (var ms = new MemoryStream())
{
   bitmap.Save(ms, ImageFormat.Bmp); //not very efficient either
   ms.Position = 0;
   return ImageUtils.load(ms); //the 3rd party API
}

I have tried to create UnmanagedMemoryStream directly from the image:

byte* pointer = (byte*)image.Ptr.ToPointer();
int length = image.Height*image.Width*3;
var unmanagedMemoryStream = new UnmanagedMemoryStream(pointer, length);

but when i try to read from it, it throws an AccessViolationException: Attempted to read or write protected memory.

for (int i = 0; i < length; i++)
{
   //throw AccessViolationException at random interation, e.g i==82240, 79936, etc
   unmanagedMemoryStream.ReadByte();     
}

the length is 90419328 in this case and it shoudl be correct, because it has the same value as image.ManagedArray.Length;

How to get the stream without copying the data?


Solution

  • Ok, there is Bytes property of type byte[] on the Image() so the answer is very easy:

    new MemoryStream(image.Bytes)