如何显示使用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.ToBitmap
和Image.get_Bitmap
的源代码,了解如何实现自己的WriteableBitmap
。
http://blogs.microsoft.co.il/blogs/tamir/archive/2008/04/23/webcam-control-with-wpf-or-how-to-create-high-framerate-player-with-directshow-通过-使用- interopbitmapfunction于WPF的application.aspx