I have an image processing function written in C++ based on opencv. In my wpf application I have used AForge library to access a webcam and update it on UI. This the function for handling newframes.
void UI_NewFrame(object sender, NewFrameEventArgs eventArgs)
{
try
{
System.Drawing.Bitmap bitmapFrame = (Bitmap)eventArgs.Frame.Clone();
MemoryStream ms = new MemoryStream();
bitmapFrame.Save(ms, ImageFormat.Bmp);
ms.Seek(0, SeekOrigin.Begin);
BitmapImage bitmapImageFrame = new BitmapImage();
bitmapImageFrame.BeginInit();
bitmapImageFrame.StreamSource = ms;
bitmapImageFrame.EndInit();
bitmapImageFrame.Freeze();
CurrentFrame = bitmapImageFrame;
}
catch (Exception ex)
{
Debug.WriteLine("fatal::" + ex.Message);
}
}
This my c++ code:
void FaceTracker(unsigned char* imageBuffer, int width, int height){
Mat frame(Size(width, height), CV_8UC4, imageBuffer, Mat::AUTO_STEP);
Mat gray;
cvtColor(frame, gray, COLOR_BGR2GRAY);
//do more operations
}
I have two options. I have already found a code for copying data from BitmapImage
to a IntPtr
buffer using CopyPixels
. I tested it and it works fine. But I also read I can simply pass a handle to the Bitmap using GetHBitmap
. However this is not working for me. I read this How can I pass a .NET Bitmap to a native DLL? but I don't understand the part about GetDIBits
. I also tried locking pixels of bitmap and passing like this:
bitmapFrame.LockBits(new Rectangle(0, 0, bitmapFrame.Width, bitmapFrame.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite,
System.Drawing.Imaging.PixelFormat.Format24bppRgb);
NativeFunctions.FaceTracker(bitmapFrame.GetHbitmap(), bitmapFrame.Width, bitmapFrame.Height);
and simply passing HBitMap, neither works. I always get an exception stating memory access violation.
LockBits
, and passScan0
.GetHbitmap
is not at all the same asScan0
. – Handbook