如何显示使用Emgu捕获的网络摄像头图像?

我目前正在开发一个使用面部识别的项目。 因此,我需要一种向用户显示网络摄像头图像的方法,以便他可以调整他的脸部。

我一直在尝试使用尽可能少的CPU来从网络摄像头获取图像:

  • VideoRendererElement
  • WPFMediaKit
  • DirectShow的库

但它们都不是很好……无论是太慢还是太耗费CPU资源。

然后我尝试了Emgu库 ,我觉得很棒。 起初,我在Windows窗体项目中尝试了它,并在图片框中更新图像。 但是,当我试图将它集成到我的WPF项目中时,我遇到了如何将我的图像传递给我的Image控件的问题。

现在,我有以下源代码:

             

而背后的代码:

 private Capture capture; private System.Timers.Timer timer; public Window1() { InitializeComponent(); } private void Window_Loaded(object sender, RoutedEventArgs e) { capture = new Capture(); capture.FlipHorizontal = true; timer = new System.Timers.Timer(); timer.Interval = 15; timer.Elapsed += new ElapsedEventHandler(timer_Elapsed); timer.Start(); } void timer_Elapsed(object sender, ElapsedEventArgs e) { using (Image frame = capture.QueryFrame()) { if (frame != null) { var bmp = frame.Bitmap; // How do I pass this bitmap to my Image control called "webcam"? } } } private void Window_Closing(object sender, CancelEventArgs e) { if (capture != null) { capture.Dispose(); } } 

我的猜测是使用BitmapSource / WriteableBitmap,但我没有让它们工作……

谢谢!

Image Class有一个你可能正在寻找的UriSource属性

查看Emgu wiki – >教程 – >示例 – > WPF(Windows Presentation Foundation)它包含以下代码片段,用于将IImage转换为BitmapSource,您可以直接将其应用于控件。

使用Emgu.CV; 使用System.Runtime.InteropServices; …

  ///  /// Delete a GDI object ///  /// The poniter to the GDI object to be deleted ///  [DllImport("gdi32")] private static extern int DeleteObject(IntPtr o); ///  /// Convert an IImage to a WPF BitmapSource. The result can be used in the Set Property of Image.Source ///  /// The Emgu CV Image /// The equivalent BitmapSource 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; } } 

我估计你要找的是这个:

 Image frame = capture.QueryFrame(); pictureBox1.Image = image.ToBitmap(pictureBox1.Width, pictureBox1.Height); 

如果你正在使用WPF和MVVM,那么你将如何使用EMGU 。

视图:

             

视图模型:

 namespace HA.FacialRecognition.Enroll.ViewModels { public class PhotoCaptureViewModel : INotifyPropertyChanged { public PhotoCaptureViewModel() { StartVideo(); } private DispatcherTimer Timer { get; set; } private Capture Capture { get; set; } private BitmapSource _currentFrame; public BitmapSource CurrentFrame { get { return _currentFrame; } set { if (_currentFrame != value) { _currentFrame = value; OnPropertyChanged(); } } } private void StartVideo() { Capture = new Capture(); Timer = new DispatcherTimer(); //framerate of 10fps Timer.Interval = TimeSpan.FromMilliseconds(100); Timer.Tick += new EventHandler(async (object s, EventArgs a) => { //draw the image obtained from camera using (Image frame = Capture.QueryFrame()) { if (frame != null) { CurrentFrame = ToBitmapSource(frame); } } }); Timer.Start(); } 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, BitmapSizeOptions.FromEmptyOptions()); DeleteObject(ptr); //release the HBitmap return bs; } } ///  /// Delete a GDI object ///  [DllImport("gdi32")] private static extern int DeleteObject(IntPtr o); //implementation of INotifyPropertyChanged, viewmodel disposal etc } 

我相信你必须使用互操作( 来源 ):

 using System.Windows.Interop; using System.Windows.Media.Imaging; public static ImageSource AsImageSource( this Image image) where TColor : IColor, new() { return Imaging.CreateBitmapSourceFromHBitmap(image.Bitmap.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions()); } 

可以这样使用:

 void timer_Elapsed(object sender, ElapsedEventArgs e) { using (Image frame = capture.QueryFrame()) { if (frame != null) { var bmp = frame.AsImageSource(); } } } 

如果互Image.ToBitmap不够好,请查看Image.ToBitmapImage.get_Bitmap的源代码,了解如何实现自己的WriteableBitmap

试试这个。

http://easywebcam.codeplex.com/

我用它,它很棒..