Wednesday, October 19, 2016

EmguCV dengan C# - Tutorial Part 4 : Koneksi Webcam

Wah, nggak terasa udah hampir 1 minggu nggak update Blog. Soalnya ada trouble dengan PC saya sehingga tidak bisa post blog. Kali ini saya akan memberikan tutorial untuk akses webcam dan pengolahan citra secara waktu nyata dengan EmguCV.

Source code : https://drive.google.com/file/d/0B7pb7LWFao_ddU1xUTVNUDNZdFU/view?usp=sharing

Ok, seperti biasa kita akan mulai sebuah project baru. Layoutnya sederhana saja, hanya perlu ImageBox, Button dan ComboBox. ComboBox di sini digunakan untuk memilih perangkat webcam yang tersedia (jika ada lebih dari satu).


Untuk bisa mencari perangkat webcam yang terpasang, kita akan menggunakan pustaka DirectShow yang bisa didownload di sini :
http://directshownet.sourceforge.net/
Ekstrak, masukkan file "DirectShowLib-2005.dll" dari folder "bin" ke project reference.

Setelah itu masukkan code dibawah :
using DirectShowLib;
using Emgu.CV;
using Emgu.CV.Structure;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace TutorialPart4
{
    public partial class MainForm : Form
    {
        private CascadeClassifier cascadeFace;
        private Capture capture = null;
        private Mat capturedImage = new Mat();
        private Mat imageToView = new Mat();
        private Mat grayImage = new Mat();
        private Rectangle[] detectedFace;
        private bool captureInProgress = false;
        private int selectedDevice = 0;

        public MainForm()
        {
            InitializeComponent();
            cascadeFace = new CascadeClassifier("haarcascade_frontalface_default.xml");
            listingCamera();
        }

        private void listingCamera()
        {
            DsDevice[] cameras = DsDevice.GetDevicesOfCat(FilterCategory.VideoInputDevice);
            for (int i = 0; i < cameras.Length; i++)
                comboBoxCamera.Items.Add(cameras[i].Name);
            if (cameras.Length > 0) comboBoxCamera.SelectedIndex = 0;
        }

        private void ProcessFrame(object sender, EventArgs args)
        {
            capture.Retrieve(capturedImage);
            imageToView = capturedImage.Clone();

            // Ini adalah bagian deteksi wajah
            CvInvoke.CvtColor(imageToView, grayImage, Emgu.CV.CvEnum.ColorConversion.Bgr2Gray);
            detectedFace = cascadeFace.DetectMultiScale(grayImage, 1.1, 10, new Size(100, 100));
            int i = 1;
            foreach (Rectangle faceRegion in detectedFace)
            {
                CvInvoke.Rectangle(imageToView, faceRegion, new Bgr(Color.Red).MCvScalar, 2);
                CvInvoke.PutText(imageToView, i.ToString(), new Point(faceRegion.X + 10, faceRegion.Y + 35),
Emgu.CV.CvEnum.FontFace.HersheySimplex, 1, new Bgr(Color.Red).MCvScalar, 2);
                i++;
            }

            displayImage();
        }

        private void displayImage()
        {
            if (this.InvokeRequired)
                try
                {
                    this.Invoke(new MethodInvoker(delegate() { displayImage(); }));
                }
                catch { }
            else
                imageBox1.Image = imageToView;
        }

        private void setupCapture()
        {
            if (comboBoxCamera.SelectedIndex != selectedDevice)
                if (capture != null)
                    disposeCapture();
            if (capture == null)
            {
                selectedDevice = comboBoxCamera.SelectedIndex;
                capture = new Capture(comboBoxCamera.SelectedIndex);
                capture.SetCaptureProperty(Emgu.CV.CvEnum.CapProp.FrameWidth, 1280);
                capture.SetCaptureProperty(Emgu.CV.CvEnum.CapProp.FrameHeight, 720);
                capture.SetCaptureProperty(Emgu.CV.CvEnum.CapProp.Fps, 15);
                capture.ImageGrabbed += ProcessFrame;
            }
        }

        private void buttonCapture_Click(object sender, EventArgs e)
        {
            setupCapture();
            if (capture != null)
            {
                if (!captureInProgress)
                {
                    capture.Start();
                    buttonCapture.Text = "STOP";
                }
                else
                {
                    capture.Stop();
                    buttonCapture.Text = "START";
                }
            }
        }

        private void disposeCapture()
        {
            if (capture != null)
            {
                capture.Dispose();
                capture = null;
            }
        }

        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            disposeCapture();
        }
    }
}

Code di atas sederhana saja. Awalnya kita inisialisasi kamera pada fungsi setupCamera(). Pada contoh di atas, saya set lebar dan tinggi frame sebesar 1280x720 piksel dengan frame rate 15 fps. Sobat dapat menggantinya sesuai spesifikasi kamera. Jika diisi nilai terlalu besar, maka otomatis digunakan resolusi dan fps terbesar yang bisa dihandle kamera. Kemudian kita tambahkan thread event ImageGrabbed dengan ProcessFrame.

Pada setiap frame yang diambil, kita lakukan deteksi wajah dengan perintah cascadeFace.DetectMultiScale(grayImage, 1.1, 10, new Size(100, 100)); Di sini saya pakai nilai minNeighbor = 10 dan minSize = 100x100. Hal ini dikarenakan resolusi kamera yang saya pakai sebesar 1280x720. Sehingga perlu dibatasi minimum ukuran wajah dan tetangga yang terdeteksi. Apa maksudnya minNeighbor? Parameter tersebut adalah batasan untuk menentukan deteksi wajah harus memiliki minimal 10 tetangga. Jika diisi nilai yang terlalu rendah, maka akan ada banyak wajah terdeteksi yang bertumpuk satu sama lain. Sobat dapat mencoba-coba parameter fungsi di atas, disesuaikan saja dengan resolusi kamera yang sobat gunakan.

Setelah itu coba run aplikasi yang sudah dibuat. Contoh hasilnya :


Deteksi wajah dengan haar cascade classifier ini lumayan strong deteksinya. Bisa dilihat biarpun kamera saya jelek begitu masih terdeteksi juga wajahnya. Maklum, webcam low budget Logitech HD Webcam C270. Ga ada autofocus, jadinya kalau terlalu dekat ngeblur, hehehe. Tapi lumayan lah ini webcam daripada webcam abal-abal 50ribuan.

Demikian tutorial kali ini. Part selanjutnya, ehm tentang apa ya? Ntar lah aku coba pikir lagi.

Salam luar biasa,
ErinQvnm

No comments:

Post a Comment