2012-03-26 12 views
0

Ich möchte Kinect und EmguCV zusammen verwenden. Ich habe es geschafft, Bilder von Kinect zu bekommen und ein Image-Objekt von EmguCV zu erstellen. Ich habe die Anwendung für einen Moment ausgeführt und die Anwendung stürzt nach einiger Zeit ab, weil der Speicher nicht richtig freigegeben wird.Kinect & EmguCV & GC

Das kleine Stück Code liefert RGB-Farbbilder von Kinect und wandelt sie in HSV-Farbbilder um. Ich bin nicht in der Lage herauszufinden, wo der Speicher nicht freigegeben ist. Ich habe "Strukturen verwenden" verwendet, genauso wie die Beispiele, die ich im Internet und in einem Buch gelesen habe.

Ich möchte einen Rat bekommen, was ich falsch im Code mache, weil ich C# nicht sehr gut kenne und ich muss mein Bein, das die Bilddaten konvertiert, gezogen haben. Ich bin auch daran interessiert, andere einfache Kinect + EmguCV-Projekte zu sehen. Ich wäre Ihnen sehr dankbar, wenn Sie mir etwas empfehlen würden.

Vielen Dank im Voraus.

Dies ist der Code:

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

Antwort

0

Es gibt eine Menge undisposed Bitmaps ist in dem Code herumliegen, lassen Sie mich ihnen hinweisen:

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

Es wahrscheinlich mehr Lecks ist. Grundregel ist, dass jede verfügbare Ressource (wie Bitmap) erstellt wird (auf jeden Fall alle reinen Funktionen, die Bitmaps zurückgeben, müssen sie entfernt werden), nachdem Sie mit ihnen fertig sind.

Denken Sie daran, dass Sie niemals eine Bitmap entsorgen sollten, wenn sie aktuell an ein Control gebunden ist oder anderweitig verwendet wird. Ersetzen Sie es durch ein frisches und entsorgen Sie dann das alte.

+0

Danke, ich werde es versuchen, sobald ich kann und ich werde kommentieren. – honnix

+0

Ich kann oldBmp.Dispose() nicht kompilieren. Welchen anderen Weg könnte ich die Bilder entsorgen? – honnix

+0

Welcher Typ ist oldBmp? Vielleicht müssen Sie es in Bitmap umwandeln? –