使用C#調用mingw的動態庫實現視頻識別軟件,程序經過C++調用opencv打開視頻,將圖像的原始數據以rgb24的方式傳遞給C#端,C#經過構造圖像對象給控件賦值的方式顯示圖片。windows
一開始使用wpf的控件image:多線程
1 while (true) 2 { 3 S_IMG simg = Mingw.display(); //調用取圖像函數 4 int size = simg.w * simg.h * 3; 5 byte[] data = new byte[size]; 6 Marshal.Copy(simg.pbuf, data, 0, size); 7 Dispatcher.Invoke((EventHandler)delegate 8 { 9 WriteableBitmap bitmap = new WriteableBitmap(simg.w, simg.h, 100, 100, PixelFormats.Rgb24, null); 10 bitmap.WritePixels(new Int32Rect(0, 0, simg.w, simg.h), data, simg.w * 3, 0); 11 img1.Source = bitmap; 12 BitmapEncoder encoder = new JpegBitmapEncoder(); 13 encoder.Frames.Add(BitmapFrame.Create(bitmap)); 14 encoder.Save(new System.IO.FileStream(pics.ToString()+".jpg", System.IO.FileMode.Create)); 15 pics++; 16 }, new object[2]); 17 }
其中img1是圖像控件。函數
此方法顯示視頻時,若是幀率太高(測試時打開了一個AVI文件,讀取幀的時候沒有延時)則圖像會閃黑屏。一開始懷疑是C++部分程序多線程同步問題,後來加入了第12~15行代碼,將C#收到的圖像保存下來,結果圖片徹底沒問題,就是image控件顯示時出現了黑屏狀況。經調試無效後,決定使用winform的圖像控件。測試
首先在工程中引用:spa
System.Windows.Froms線程
WindowsFormsIntegration調試
而後在xaml中添加:code
xmlns:wfi="clr-namespace:System.Windows.Forms.Integration;assembly=WindowsFormsIntegration"orm
xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"視頻
在控件處添加:
<WindowsFormsHost Name="windowsFormsHost1" Grid.Row="1" Grid.Column="0">
<wf:PictureBox Name="picturebox1"/>
</WindowsFormsHost>
在C#代碼中添加:
public System.Windows.Forms.PictureBox picb1;
初始化時添加:
picb1 = windowsFormsHost1.Child as System.Windows.Forms.PictureBox;
顯示代碼:
1 while (true) 2 { 3 S_IMG simg = Mingw.display(); //調用取圖像函數 4 Dispatcher.Invoke((EventHandler)delegate 5 { 6 System.Drawing.Bitmap bitmap=new Bitmap(simg.w,simg.h,simg.w*3,System.Drawing.Imaging.PixelFormat.Format24bppRgb,simg.pbuf); 7 picb1.Image=bitmap; 8 }, new object[2]); 9 }
就不閃了,代碼也清爽多了。不過wpf和winform的圖像像素格式是反的,分不清哪一個是RGB哪一個是BGR了。