How to display webcam images captured with Emgu?

18,315

Solution 1

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

Solution 2

I reckon all you're looking for is this:

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

Solution 3

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

}
Share:
18,315
user1198301
Author by

user1198301

Updated on July 25, 2022

Comments

  • user1198301
    user1198301 almost 2 years

    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!

  • user1198301
    user1198301 about 15 years
    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...
  • dahlbyk
    dahlbyk about 15 years
    Setting the Source should be sufficient. You could try specifying an Int32Rect with the size of the image?
  • Ievgen
    Ievgen about 13 years
    I have the same issue! And maging.CreateBitmapSourceFromHBitmap(image.Bitmap.GetHbitmap‌​(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions()); causes memory leaks in WPF!