• 在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了!原生的就是好用,速度很令人满意。


    本博客所有博文,若无专门说明皆为原创,转载请注明作者和出处!
  • 相关阅读:
    ng2-bootstrap的modal嵌套时无法滚动的情况
    oracle自动补0
    webservice 从客户端中检测到有潜在危险的 Request.Form 值
    树莓派花生壳
    ubuntu E: Could not get lock /var/lib/dpkg/lock
    树莓派配置静态ip
    解决PL/SQL查询结果乱码的问题
    批处理脚本命令行方式关闭Windows服务
    最简单的分享到微博代码
    Select的onchange事件
  • 原文地址:https://www.cnblogs.com/ifinver/p/2828689.html
Copyright © 2020-2023  润新知