Search code examples
c#kinectemgucv

Converting from WriteableBitmap to Mat for then showing it in a window with CvInvoke.Imshow?


I'm fetching infrared frames from a Kinect V2 camera. The frames come in the form of WritableBitmap, so I try to convert it with this code that I made:

public Mat WritableBitmapToMat(WriteableBitmap writeBmp)
{
    Bitmap bmp;
    using (MemoryStream outStream = new MemoryStream())
    {
        BitmapEncoder enc = new BmpBitmapEncoder();
        enc.Frames.Add(BitmapFrame.Create((BitmapSource)writeBmp));
        enc.Save(outStream);
        bmp = new Bitmap(outStream);
    }

    Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);

    BitmapData bmpData = bmp.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, bmp.PixelFormat);

    IntPtr data = bmpData.Scan0;

    int step = bmpData.Stride;

    Mat mat = new Mat(bmp.Height, bmp.Width, Emgu.CV.CvEnum.DepthType.Cv32F, 4, data, step);

    bmp.UnlockBits(bmpData);

    return mat;
}

I don't know if it's a problem with the conversion, but when I try to show the image in a window with this code:

CvInvoke.Imshow("window showing a picture", infraredMat);

I end up getting an exception that looks like this:

Exception: Exception thrown: 'System.AccessViolationException' in Emgu.CV.World.dll ("Attempted to read or write protected memory. This is often an indication that other memory is corrupt.").

I also want to mention I am using EmguCV 3.1 and Kinect SDK 2.0

Thanks in advance for any help I get.


Solution

  • If you look at the InfraredBasics-WPF example in the Kinect 2.0 SDK, the IR images are fetched into a ushort vector from the FrameReference.AcquireFrame()method. Then you can use the IntPtr infraredBuffer.UnderlyingBuffer to access the frame data (in an unsafe method) to get the 1-D vector. You can later convert a 1-D to 2-D matrix if required using the standard 2xfor loops.

    This way you won't have to access the data from the `BitmapEncoder. Plus, since it's given as a standard example in the SDK, it's the recommended method for getting the IR frames I think. Furthermore, the example also contains the method for displaying the IR images; unless you have a specific method/reason to use your way.