tags:

views:

3305

answers:

7

Hello,

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 been trying a lot of things to get images from the webcam using as less CPU as possible:

But none of them were fine... Either way too slow or too CPU resources consuming.

Then I tried the Emgu library and I felt great about it. At first, I tried it in a Windows Form project and was updating the image in a Picture Box. But then, when I tried to integrate it in my WPF Project I got stuck on how to pass my image to my Image control..

Right now, I've the following source code:

<Window x:Class="HA.FacialRecognition.Enroll.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Window1" Width="800" Height="600"
        Loaded="Window_Loaded" Closing="Window_Closing">
    <Grid>
        <Image x:Name="webcam" Width="640" Height="480" >
            <Image.Clip>
                <EllipseGeometry  RadiusX="240" RadiusY="240">
                    <EllipseGeometry.Center>
                        <Point X="320" Y="240" />
                    </EllipseGeometry.Center>
                </EllipseGeometry>
            </Image.Clip>
        </Image>
    </Grid>
</Window>

And the code behind:

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<Bgr, byte> 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();
 }
}

My guess was to use BitmapSource/WriteableBitmap but I did not get them working...

Thanks!

+1  A: 

Image Class has got a UriSource property that you may be looking for

Ankit
A: 

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.

dahlbyk
Yeah, but what do I need to do to make my "webcam" Image Control display the image?I've tried : webcam.Source = frame.AsImageSource();But it doesn't display anything...
ZogStriP
Setting the Source should be sufficient. You could try specifying an Int32Rect with the size of the image?
dahlbyk
A: 

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;
        }
    }
+1  A: 

I reckon all you're looking for is this:

Image<Bgr, Byte> frame = capture.QueryFrame();
pictureBox1.Image = image.ToBitmap(pictureBox1.Width, pictureBox1.Height);
Tom Wright
A: 

Try this.

http://easywebcam.codeplex.com/

I used it and it was excellent..

femi
A: 

Hi guys,

could you post an sample code working?

Thanks.