I\'m currently working on a project that use Facial Recognition. I therefore need a way to display the webcam images to the user so he can adjust his face.
I\'ve bee
If you are using WPF and MVVM here is how you would do it using EMGU.
View:
<Window x:Class="HA.FacialRecognition.Enroll.Views.PhotoCaptureView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Width="800" Height="600">
<Grid>
<Image Width="640" Height="480" Source="{Binding CurrentFrame}">
<Image.Clip>
<EllipseGeometry RadiusX="240" RadiusY="240">
<EllipseGeometry.Center>
<Point X="320" Y="240" />
</EllipseGeometry.Center>
</EllipseGeometry>
</Image.Clip>
</Image>
</Grid>
Viewmodel:
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<Bgr, byte> 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;
}
}
/// <summary>
/// Delete a GDI object
/// </summary>
[DllImport("gdi32")]
private static extern int DeleteObject(IntPtr o);
//implementation of INotifyPropertyChanged, viewmodel disposal etc
}
I reckon all you're looking for is this:
Image<Bgr, Byte> frame = capture.QueryFrame();
pictureBox1.Image = image.ToBitmap(pictureBox1.Width, pictureBox1.Height);
Image Class has got a UriSource property that you may be looking for
I believe you have to use interop (source):
using System.Windows.Interop;
using System.Windows.Media.Imaging;
public static ImageSource AsImageSource<TColor, TDepth>(
this Image<TColor, TDepth> image) where TColor : IColor, new()
{
return Imaging.CreateBitmapSourceFromHBitmap(image.Bitmap.GetHbitmap(),
IntPtr.Zero, Int32Rect.Empty,
BitmapSizeOptions.FromEmptyOptions());
}
Which could be used like this:
void timer_Elapsed(object sender, ElapsedEventArgs e)
{
using (Image<Bgr, byte> frame = capture.QueryFrame())
{
if (frame != null)
{
var bmp = frame.AsImageSource();
}
}
}
If the interop doesn't perform well enough, take a look at the source of Image.ToBitmap
and Image.get_Bitmap
to see how you could implement your own 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-by-using-interopbitmap-in-wpf-application.aspx
Look on the Emgu wiki -> Tutorials -> Examples -> WPF (Windows Presentation Foundation) It contains the following code snippet to convert your IImage to a BitmapSource, which you can directly apply to your control.
using Emgu.CV; using System.Runtime.InteropServices; ...
/// <summary>
/// Delete a GDI object
/// </summary>
/// <param name="o">The poniter to the GDI object to be deleted</param>
/// <returns></returns>
[DllImport("gdi32")]
private static extern int DeleteObject(IntPtr o);
/// <summary>
/// Convert an IImage to a WPF BitmapSource. The result can be used in the Set Property of Image.Source
/// </summary>
/// <param name="image">The Emgu CV Image</param>
/// <returns>The equivalent BitmapSource</returns>
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;
}
}