Kinect & EmguCV & GC - PullRequest
       30

Kinect & EmguCV & GC

0 голосов
/ 27 марта 2012

Я бы хотел использовать Kinect и EmguCV вместе. Мне удалось получить изображения из Kinect и создать объект Image EmguCV. Я запустил приложение на мгновение, и приложение через некоторое время вылетает, потому что память не высвобождается должным образом.

Небольшой фрагмент кода получает изображения RGB-цвета от Kinect и преобразует их в изображения цвета 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;
    }

1 Ответ

0 голосов
/ 27 марта 2012

В коде лежит много неразмещенных растровых изображений, позвольте мне указать на них:

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

Возможно, есть еще утечки.Основное правило заключается в том, что каждый созданный одноразовый ресурс (например, растровое изображение) (любым способом, все чистые функции, возвращающие растровые изображения, создают их) необходимо утилизировать после того, как вы поработаете с ним.

Имейте в виду, что выникогда не должен располагать растровое изображение, если оно в настоящее время связано с каким-либо элементом управления или используется иным образом.Замените его новым, а затем утилизируйте старый.

...