打开 CV GUI 错误处理程序 - 内存不足

发布于 2024-11-17 09:56:26 字数 4811 浏览 1 评论 0原文

我目前在一个站点上有几个站点,他们刚刚报告其中一个站点显示以下错误:

打开 CV GUI 错误处理程序

内存不足(内存不足) 在函数 cvAlloc, .cvalloc.cpp(111) 中,

这些机器执行的操作很少,它们连接到 Suprema RealScan 生物识别手指扫描仪: http://www.supremainc.com/eng/product/ls_20.php?mark=52

我怀疑问题来了来自以下内容:

作为此设备 SDK 的一部分,您可以注册“预览回调”。这意味着当设备启动时,此回调将触发并提供指向图像的指针,该图像是来自扫描仪的实际图像。使用此功能,您可以在用户将手指放在设备上时显示其实时图像。当设备处于捕获模式时,回调每隔几毫秒触发一次。当设备停止捕获回调时停止。

当我们开始集成 SDK 时,我们意识到它允许我们将此图像指针转换为 C# 图像类型的唯一方法是通过将指针数据保存到文件的函数。然后,我们必须从创建的文件中读回图像,并删除该文件。我们认为这有点疯狂,因此向他们的支持人员发送了电子邮件,询问是否有一种方法可以将图像指针转换为代码中的 C# 图像,而无需先使用他们的 SDK 将其保存到文件中。

他们为我们提供了以下功能(他们说尚未经过测试,实际上是有人刚刚编写的),我相信这就是此错误的来源,因为其他一切都非常基本:

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);
        }
    }

注释是我自己添加的我一直试图理解这里实际发生的事情,但我仍然不认为我完全理解他们在做什么。它确实有效,并且我在测试期间没有遇到该错误,但显然在长时间大量使用后会弹出此错误。

我希望有人能够更好地理解他们向我提供的代码,并突出显示可能导致问题的任何区域?

任何帮助表示赞赏! 问候 阿德里安

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

无悔心 2024-11-24 09:56:26

最终我发现了内存泄漏。

I found the memory leak, eventually.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文