2012-03-26 21 views
0

我想一起使用Kinect和EmguCV。我設法從Kinect獲取圖像並創建一個EmguCV的圖像對象。我已經運行了一段時間的應用程序,並且應用程序在一段時間後崩潰,因爲內存未正確釋放。Kinect&EmguCV&GC

這段代碼從Kinect獲取RGB彩色圖像並將它們轉換爲HSV彩色圖像。我無法確定內存未被釋放的位置。我使用過「使用結構」,就像我在互聯網和某本書中讀過的例子。

我想得到一些關於我在代碼中做錯了什麼的建議,因爲我對C#不是很熟悉,而且我一定會拉我的腿來轉換圖像數據。我對看到其他簡單的Kinect + EmguCV項目感興趣,如果您有任何建議,我將非常感激。

在此先感謝。

這是代碼:

private void showHSV(Bitmap bmp) 
    { 
     Image<Bgr, byte> img = new Image<Bgr, byte>(bmp); 
     Image<Hsv, byte> imgHsv = img.Convert<Hsv, byte>(); 

     Bitmap bmp2 = imgHsv.ToBitmap(); 

     image2.Source = sourceFromBitmap(bmp2); 
    } 


    private BitmapSource sourceFromBitmap(Bitmap bmp) 
    { 
     BitmapSource bs = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
      bmp.GetHbitmap(), 
      IntPtr.Zero, 
      System.Windows.Int32Rect.Empty, 
      BitmapSizeOptions.FromWidthAndHeight(bmp.Width, bmp.Height)); 

     return bs; 
    } 

    private void ColorImageReady(object sender, ColorImageFrameReadyEventArgs e) 
    { 
     using (ColorImageFrame imageFrame = e.OpenColorImageFrame()) 
     { 
      if (imageFrame != null) 
      { 
       byte[] pixelData = new byte[imageFrame.PixelDataLength]; 
       imageFrame.CopyPixelDataTo(pixelData); 

       BitmapSource bmp = BitmapImage.Create(imageFrame.Width, imageFrame.Height, 96, 96, PixelFormats.Bgr32, null, 
        pixelData, imageFrame.Width * imageFrame.BytesPerPixel); 

       image1.Source = bmp; 

       showHSV(bitmapFromSource(bmp)); 
      } 
      else 
      { 
       // imageFrame is null because the request did not arrive in time   } 
      } 
     } 
    } 

    private System.Drawing.Bitmap bitmapFromSource(BitmapSource bitmapsource) 
    { 
     System.Drawing.Bitmap bitmap; 

     using (System.IO.MemoryStream outStream = new System.IO.MemoryStream()) 
     { 
      BitmapEncoder enc = new BmpBitmapEncoder(); 
      enc.Frames.Add(BitmapFrame.Create(bitmapsource)); 
      enc.Save(outStream); 
      bitmap = new System.Drawing.Bitmap(outStream); 
     } 
     return bitmap; 
    } 

回答

0

有很多未予處置位圖中的代碼躺在身邊,讓我指出來:

private void showHSV(Bitmap bmp) 
{ 
    Image<Bgr, byte> img = new Image<Bgr, byte>(bmp); // Not sure what Image<,> is, but I guess it needs disposing at some point 
    Image<Hsv, byte> imgHsv = img.Convert<Hsv, byte>(); // same here 

    Bitmap bmp2 = imgHsv.ToBitmap(); // bmp2 is never disposed in your code 
    var oldBmp = image2.Source; 
    image2.Source = sourceFromBitmap(bmp2); 
    oldBmp.Dispose() // try this 
} 


private BitmapSource sourceFromBitmap(Bitmap bmp) 
{ 
    BitmapSource bs = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
     bmp.GetHbitmap(), 
     IntPtr.Zero, 
     System.Windows.Int32Rect.Empty, 
     BitmapSizeOptions.FromWidthAndHeight(bmp.Width, bmp.Height)); 

    return bs; 
} 

private void ColorImageReady(object sender, ColorImageFrameReadyEventArgs e) 
{ 
    using (ColorImageFrame imageFrame = e.OpenColorImageFrame()) 
    { 
     if (imageFrame != null) 
     { 
      byte[] pixelData = new byte[imageFrame.PixelDataLength]; 
      imageFrame.CopyPixelDataTo(pixelData); 

      BitmapSource bmp = BitmapImage.Create(imageFrame.Width, imageFrame.Height, 96, 96, PixelFormats.Bgr32, null, 
       pixelData, imageFrame.Width * imageFrame.BytesPerPixel); // bmp never disposed 

      var oldBmp = image1.Source; 
      image1.Source = bmp; 
      oldBmp.Dispose(); // try so 

      showHSV(bitmapFromSource(bmp)); // what happens inside? bmp needs to be disposed at some point... 
     } 
     else 
     { 
      // imageFrame is null because the request did not arrive in time   } 
     } 
    } 
} 

private System.Drawing.Bitmap bitmapFromSource(BitmapSource bitmapsource) 
{ 
    System.Drawing.Bitmap bitmap; 

    using (System.IO.MemoryStream outStream = new System.IO.MemoryStream()) 
    { 
     BitmapEncoder enc = new BmpBitmapEncoder(); 
     enc.Frames.Add(BitmapFrame.Create(bitmapsource)); 
     enc.Save(outStream); 
     bitmap = new System.Drawing.Bitmap(outStream); 
    } 
    return bitmap; 
} 

很可能有更多的泄漏。基本規則是,創建完畢的每個可任意處理的資源(比如Bitmap)都必須在完成之後處理掉(無論如何,所有返回Bitmap的純函數都會創建它們)。

請記住,如果當前綁定到某個控件或使用其他方式,則不應該放置位圖。把它換成新的,然後丟棄舊的。

+0

謝謝,我會盡快嘗試,我會評論。 – honnix 2012-03-26 21:55:20

+0

我無法編譯oldBmp.Dispose()。還有哪種方式可以處理圖像? – honnix 2012-04-06 09:41:04

+0

oldBmp是什麼類型?也許你需要將它投射到位圖? – 2012-04-07 13:58:43