很多使用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的控件。

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