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.
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.