将位图源转换为位图会占用大量CPU使用量

时间:2014-02-25 19:49:55

标签: c# wpf c#-4.0 bitmap emgucv

我正在使用kinect !!我得到一个帧然后我将其转换为位图以便使用Emgucv转换灰度帧然后将位图转换为bitmpa源以便在窗口中显示!我是使用C#visual studio WPF !但我的程序消耗了大量的CPU使用量,以防视频被冻结了几秒钟!!我猜这是转换bitmpa源到位图和反面

byte[] colorData = null;
WriteableBitmap colorImageBitmap = null;

void myKinect_ColorFrameReady(object sender, ColorImageFrameReadyEventArgs e)
{

    using (ColorImageFrame colorFrame = e.OpenColorImageFrame())
    {

        if (colorFrame == null) return;

        if (colorData == null)
            colorData = new byte[colorFrame.PixelDataLength];

        colorFrame.CopyPixelDataTo(colorData);

            if (colorImageBitmap == null)
            {
                this.colorImageBitmap = new WriteableBitmap(
                    colorFrame.Width,
                    colorFrame.Height,
                    96,  // DpiX
                    96,  // DpiY
                    PixelFormats.Bgr32,
                    null);
            }

            this.colorImageBitmap.WritePixels(
                new Int32Rect(0, 0, colorFrame.Width, colorFrame.Height),
                colorData, // video data
                colorFrame.Width * colorFrame.BytesPerPixel, // stride,
                0   // offset into the array - start at 0
                );


            Image<Gray, Byte> My_Image = new Image<Gray, byte>(BitmapFromSource(colorImageBitmap));
            kinectVideo.Source = ToBitmapSource(My_Image);


    }
}



private System.Drawing.Bitmap BitmapFromSource(BitmapSource bitmapsource)
{
    System.Drawing.Bitmap bitmap;
    using (MemoryStream outStream = new MemoryStream())
    {
        BitmapEncoder enc = new BmpBitmapEncoder();
        enc.Frames.Add(BitmapFrame.Create(bitmapsource));
        enc.Save(outStream);
        bitmap = new System.Drawing.Bitmap(outStream);

    }
    return bitmap;

}

 [DllImport("gdi32")]
private static extern int DeleteObject(IntPtr o);


 public static BitmapSource ToBitmapSource(IImage image)
{
    using (System.Drawing.Bitmap source = image.Bitmap)
    {
        IntPtr ptr = source.GetHbitmap(); //obtain the Hbitmap

        BitmapSource bs = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
            ptr,
            IntPtr.Zero,
            Int32Rect.Empty,
            System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions());

        DeleteObject(ptr); //release the HBitmap
        return bs;
    }
}

}

1 个答案:

答案 0 :(得分:0)

而不是使用Emgucv进行灰度...这意味着你必须创建一个GDI + Bitmap(System.Drawing.Bitmap)将它传递给Emgucv,然后将它从GDI + Bitmap转换回BitmapSource,你可以使用FormatConvertedBitmap将其保留在WPF世界中。

void myKinect_ColorFrameReady(object sender, ColorImageFrameReadyEventArgs e)
{
    using (ColorImageFrame colorFrame = e.OpenColorImageFrame())
    {
        if (colorFrame == null) return;

        if (colorData == null)
            colorData = new byte[colorFrame.PixelDataLength];

        colorFrame.CopyPixelDataTo(colorData);

        if (colorImageBitmap == null)
        {
            this.colorImageBitmap = new WriteableBitmap(
                colorFrame.Width,
                colorFrame.Height,
                96,  // DpiX
                96,  // DpiY
                PixelFormats.Bgr32,
                null);
        }

        this.colorImageBitmap.WritePixels(
            new Int32Rect(0, 0, colorFrame.Width, colorFrame.Height),
            colorData, // video data
            colorFrame.Width * colorFrame.BytesPerPixel, // stride,
            0   // offset into the array - start at 0
            );

        kinectVideo.Source = new FormatConvertedBitmap(colorImageBitmap, PixelFormats.Gray32Float, null, 0);
    }
}

另一种选择是使用像素着色器,对您的“kinectVideo”元素(可能是Image元素)应用灰度效果来显示帧。