2018年12月11日 星期二

Emgu webcam capture (WPF)

Ref: https://github.com/emgucv/emgucv/tree/master/Emgu.CV.Example/FacialMouseControl
Windows 10 x64 @ ASUS X450J + Visual Studio 2017 +  Emgu 3.2.0.2721
1. Application.Idle (Form) ==> ComponentDispatcher.ThreadIdle (WPF)
2. MainWindows.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
// Ref: https://stackoverflow.com/questions/16596915/emgu-with-c-sharp-wpf
namespace wk1301
{
    // 1. nuget emgu 3.4.3
    // 2. Add using ref FaceMouse
    using Emgu.CV;
    using Emgu.CV.Structure;
    using Emgu.Util;
    using System.Threading;
    using System.Runtime.InteropServices;
    using System.Windows.Interop;

    /// <summary>
    /// MainWindow.xaml 的互動邏輯
    /// </summary>
    public partial class MainWindow : Window
    {
        private VideoCapture _capture;
        //private HaarCascade _face;
        public MainWindow()
        {
            InitializeComponent();
            if (_capture == null)
            {
                try
                {
                    _capture = new VideoCapture();
                }
                catch (NullReferenceException excpt)
                {
                    MessageBox.Show(excpt.Message);
                    return;
                }
            }

            // https://stackoverflow.com/questions/1111615/getting-inactivity-idle-time-in-a-wpf-application
            ComponentDispatcher.ThreadIdle += ComponentDispatcher_ThreadIdle;
        }

        int count = 0;
        private void ComponentDispatcher_ThreadIdle(object sender, EventArgs e)
        {
            this.Title = (count++).ToString();
            using (var imageFrame = _capture.QueryFrame().ToImage<Bgr, Byte>())
            {
                if (imageFrame != null)
                {
                    image1.Source = BitmapSourceConvert.ToBitmapSource(imageFrame);
                }
            }
        }

    }

    // Add ref: SYstem.Drawing.DLL
    public static class BitmapSourceConvert
    {
        [DllImport("gdi32")]
        private static extern int DeleteObject(IntPtr o);

        public static BitmapSource ToBitmapSource(IImage image)
        {
            using (System.Drawing.Bitmap source = image.Bitmap)
            {
                IntPtr ptr = source.GetHbitmap();

                BitmapSource bs = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
                    ptr,
                    IntPtr.Zero,
                    Int32Rect.Empty,
                    System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions());

                DeleteObject(ptr);
                return bs;
            }
        }
    }
}

3. Result:

1 則留言: