我想一起使用Kinect和EmguCV。我设法从Kinect获取图像并创建一个EmguCV的Image对象。我运行应用程序片刻,应用程序在一段时间后崩溃,因为内存未正确释放。
这段小代码从Kinect获取RGB彩色图像并将其转换为HSV彩色图像。我无法解决内存未发布的问题。我已经使用过"使用结构"就像我在互联网和某本书中读过的例子一样。
我希望得到一些关于我在代码中做错的建议,因为我不熟悉C#,我必须拉动我的腿转换图像数据。我也有兴趣看到其他-simple- 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 :(得分: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)创建(通过任何方式,所有返回Bitmaps的纯函数创建它们)都需要在完成后处理。
请记住,如果Bitmap当前绑定到某个Control或者以其他方式使用,则不应该丢弃它。用新的替换它,然后处理旧的。