2011-06-28 11 views
0

私は現時点ではサイトのいくつかの駅を持っていると、彼らはちょうどそれらのいずれかが次のエラーを表示することを報告:オープンCV GUIエラーハンドラ - メモリ不足

オープンCV GUIエラーハンドラ

不足メモリ、機能cvAllocで (メモリ不足).cvalloc.cpp(111)

これらのマシンは、彼らがSUPREMA RealScanバイオメトリック指スキャナにはほとんど接続しているん:http://www.supremainc.com/eng/product/ls_20.php?mark=52

このデバイスSDKの一部として、「プレビューコールバック」を登録することができます。つまり、デバイスが起動されると、このコールバックが起動してイメージへのポインタを提供します。このイメージはスキャナからの実際のイメージです。これは、ユーザーの指がデバイスに置かれているときに、ユーザーの指のライブイメージを表示できるようにするために使用されます。コールバックは、デバイスがキャプチャモードにある間に数ミリ秒ごとに起動します。デバイスがcallBacksのキャプチャを停止すると停止します。

SDKの統合を開始したとき、このイメージポインタをC#Image型に変換できる唯一の方法は、ポインタデータをファイルに保存したということでした。作成したファイルからイメージを読み込み、ファイルを削除する必要がありました。私たちはこれがちょっと狂っていると思って、ImageポインタをSDKでファイルに保存しなくても、コード内のC#イメージに変換する方法があるかどうかを尋ねました。

彼らは(彼らは誰かが文字通りちょうどそれを書いていた、テストされていなかったと述べた)次の関数を私たちに与えて、私は他のすべては非常に基本的なものとして、このエラーがどこから来ている、これがあると信じて:

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

ここで実際に何が起こっているのかを理解しようとしているので、コメントは自分自身で追加されています。それはうまくいく、私はテスト中にエラーを経験していないが、明らかに長期間の使用後このエラーがポップアップします。

誰かが私に提供したコードをよりよく理解し、問題を引き起こしている可能性のある領域を強調したいと考えていますか?

ご協力いただきましてありがとうございます。 よろしくお願いいたします。 Adrian

+0

あなたが求めているところは、素晴らしいメモリマップファイルの代わりに、多くの管理されていないメモリを使用していることです。ビットマップにDispose()を呼び出さないのは、ガベージコレクタが頻繁に実行されない場合の一般的なネックショットです。 SysInternalsのプロセスエクスプローラを使用して、プロセスのプライベートバイトを観察します。 –

答えて

0

最終的にメモリリークが見つかりました。