I have a few stations out at a site at the moment and they just reported that one of them displayed the following error:
Open CV GUI Error Handler
Insufficient memory (out of memory) in function cvAll开发者_开发技巧oc, .cvalloc.cpp(111)
These machines do very little, they are connecting to a Suprema RealScan Biometric finger scanner: http://www.supremainc.com/eng/product/ls_20.php?mark=52
I suspect the problem is coming from the following:
As part of this devices SDK, you have the ability to register a 'Preview CallBack'. What this means is that when the device is started, this callBack will fire and provide a pointer to an image, this image is the actual image coming from the scanner. This is used so that you can display a live image of the users fingers as they place them on the device. The callBack fires every few milliseconds while the device is in capture mode. When the device stops capturing the callBacks stop.
When we started integrating the SDK we realized that the only way that it allowed us to convert this image pointer to a C# Image type, was through a function which saved the pointer data to a file. We then had to read the image back from that file which was created, and delete the file. We thought this was a bit crazy and so emailed their support asking if there was a way of converting the Image pointer to a C# image in code without having to first save it to a file using their SDK.
They supplied us with the following function (which they said had not been tested, someone had literally just written it), and I believe this is where this error is coming from as everything else is very basic:
public void ProcessNewPreviewImage(IntPtr imageData, int imageWidth, int imageHeight)
{
try
{
if (realScanCapturing)
{
//______________________________________
// Create byte[] to store the image data
byte[] templateRawData;
//________________________________________
// Init the array to the size of this image
templateRawData = new byte[imageWidth * imageHeight];
//____________________________________
// Get the size of the image as a UINT
uint size = Convert.ToUInt32(imageWidth * imageHeight);
//__________________________________________________________
// Copy the pointer image data to the byte[] we just created
CopyMemory(templateRawData, imageData, size);
//_____________________________________________________________________
//Create a new bitmap object usign this preview images height and width
Bitmap tmpBmp = new Bitmap(imageWidth, imageHeight, System.Drawing.Imaging.PixelFormat.Format8bppIndexed);
//_________________________________________
// Create the color palette for this bitmap
System.Drawing.Imaging.ColorPalette cp = tmpBmp.Palette;
for (int i = 0; i <= 255; i++)
{
cp.Entries[i] = Color.FromArgb(i, i, i);
}
//________________________________________
// Assign this color palette to the bitmap
tmpBmp.Palette = cp;
//_________________________________________________________________
// Create a new rectangle object using the dimensions of our bitmap
Rectangle rect = new Rectangle(0, 0, tmpBmp.Width, tmpBmp.Height);
//_____________________________________________________________________________
// Create a BitmapData object (which will be used to modify the preview image?)
System.Drawing.Imaging.BitmapData tmpBMPData = null;
//________________________________________________________________________________________________
// Locks the bitmap holding the preview image into memory so that we can change it programatically
tmpBMPData = tmpBmp.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, tmpBmp.PixelFormat);
//__________________________________________________________________________
// Create new pointer pointing at the start of the image data we just locked
IntPtr ptr = tmpBMPData.Scan0;
//__________________________________________________________
// Copy the raw template data to the pointer we just created
System.Runtime.InteropServices.Marshal.Copy(templateRawData, 0, ptr, imageWidth * imageHeight);
//__________________
// Unlock the bitmap
tmpBmp.UnlockBits(tmpBMPData);
System.IO.MemoryStream msImage = new System.IO.MemoryStream();
tmpBmp.Save(msImage, ImageFormat.Bmp);
byte[] byteImage = Util.ImageToByteArray(tmpBmp);
//______________________________
// Send the extracted image data back to the client for display
thisClientServer.GetStreamingWcf(activeClientStation.VtServerDetails.ServerIpAddress, (int)activeClientStation.StreamingPort).StreamImage(byteImage);
tmpBmp.Dispose();
}
}
catch (Exception ex)
{
ShowDebugMessage("Error in ProcessNewPreviewImage: " + ex.Message);
}
}
The comments have been added by myself as I have been trying to make sense of what is actually happening here, I still don't think I fully understand what they are doing. It does work, and I haven't experienced the error during my testing, but obviously after prolonged heavy usage this error pops up.
I am hoping someone can better understand the code they have provided me with, and highlight any areas which may be causing an issue?
Any help is appreciated! Regards Adrian
I found the memory leak, eventually.
精彩评论