在WPF中使用Emgu加载Image<,>图像的两种方法

文章转自:http://www.cnblogs.com/iacocca/archive/2011/08/18/2144741.html

很多使用c#平台做图像处理的朋友都是因为要使用WPF而不得不放弃OpenCV而选择使用了Emgu。Emgu这个工具吧,由于才接触,对于OpenCV的封装好坏我不好评论,但有一点可以肯定的是,网上可以搜索的资料太少了,很多东西都需要自己研究api文档,看源代码。遇到了问题也基本上只能靠自己解决。真是魂淡啊……喷……

  (↑↑↑↑以上纯属吐槽↑↑↑↑)

  由于手上项目的原因,需要捕获摄像头,对摄像头得图像进行实时处理,并在窗口里显示出来。窗口是基于WPF的。WPF中使用过得能载图像控件就是一个Image。通过Emgu的capture函数,我们获得的图像是Image(Of TColor, TDepth)。很遗憾,Image控件是不能加载Image(Of TColor, TDepth)对象的。。

  仔细研究了一下api文档,Image(Of TColor, TDepth)类有一公共属性,是获得该对象的Bitmap。而Image控件是可以加载BitmapImage的。这两个之间是互相转换的。附上转换函数(转载自 http://blog.sina.com.cn/s/blog_6e6941e10100n2yn.html 感谢分享!):

public class GetBitmpIamge
    {
        public static BitmapImage BitmapToBitmapImage(Bitmap bitmap)
        {
            Bitmap bitmapSource = new Bitmap(bitmap.Width, bitmap.Height);
            bitmapSource.MakeTransparent();
            int i, j;
            for (i = 0; i < bitmap.Width; i++)
                for (j = 0; j < bitmap.Height; j++)
                {

                    Color pixelColor = bitmap.GetPixel(i, j);
                    Color newColor = Color.FromArgb(pixelColor.R, pixelColor.G, pixelColor.B);
                    if (newColor == Color.FromArgb(255, 0, 0, 0))
                    {
                        newColor = Color.FromArgb(255, 255, 255, 255);
                    }
                    bitmapSource.SetPixel(i, j, newColor);
                }
            MemoryStream ms = new MemoryStream();
            bitmapSource.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp);
            BitmapImage bitmapImage = new BitmapImage();
            bitmapImage.BeginInit();
            bitmapImage.StreamSource = new MemoryStream(ms.ToArray());
            bitmapImage.EndInit();
            return bitmapImage;
        }
    }


这样的确可以解决问题,图像可以很简单加载上。但使用以后你会发现这个转换的速度是完全不能满足实时的,非常的慢,更不用说还要处理了。当然,如果对于速度要求不是那么高的话,这个方法是完全可行的,而且是我现在发现最省事的方法。

  既然不能实时,那就只能另外想办法了。其实Emgu中有提供一个ImageBox的控件,封装在Emgu.CV.UI,它可以直接加载Image<,>图像。但问题是这个控件只支持Windows Form,不支持WPF。所以我们需要在WPF平台上加载Windows Form,然后再加载ImageBox的控件。

  大家可以先参考如何在WPF中加载Windows Form控件(http://www.cnblogs.com/iacocca/archive/2011/08/18/2144640.html)。这篇文章中控件是加载的button,而我们需要加载的是ImageBox。这里我们需要修改两个地方:

xmlns:WinFormControls="clr-namespace:Emgu.CV.UI;assembly=Emgu.CV.UI"
<WindowsFormsHost x:Name="cam_winform" Margin="1,0,-1,0">
            <WinFormControls:ImageBox x:Name="cam_ibox" FunctionalMode="Minimum"/>

</WindowsFormsHost>


 第二段中的FunctionalMode属性是设置ImageBox需不需要扩展功能的,比如拖动放大缩小,右键等功能。如果需要的话,就把这句去掉就好了。如果只想显示图像,想自定义一些鼠标响应的话我建议保留这句。

  这样的话就将ImageBox嵌入到WPF中了。然后直接用ImageBox.image加载图像就ok了!原生的就是好用,速度很令人满意。


本博客所有博文,若无专门说明皆为原创,转载请注明作者和出处!
原文地址:https://www.cnblogs.com/ifinver/p/2828689.html