基於Emgu CV的人臉檢測程式碼

我才是銀古發表於2013-12-23

這個提供的程式碼例子是Emgu CV提供的原始碼裡面自帶的例子,很好用,基本不需要改,程式碼做的是人臉檢測不是人臉識別,這個要分清楚。再就是新版本的Emgu CV可能會遇到系統32位和64位處理方式有區別的問題,解決的辦法不止一種,我這裡的建議在條件允許的情況下儘量使用Emgu CV的早期版本,因為越新的版本的相容性越差,早期的版本是不分32位和64位的,而且新版本的Emgu CV可能不再支援一些老的硬體,這也是選擇老版本的原因,總之,是具體情況而定吧。這裡只是給大家看看程式碼,要想執行起來,完整的解決方案,請大家去Emgu CV的官網下載相應的原始碼。

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using Emgu.CV;
using Emgu.CV.Structure;
using Emgu.CV.UI;

namespace FaceDetection
{
   static class Program
   {
      /// <summary>
      /// The main entry point for the application.
      /// </summary>
      [STAThread]
      static void Main()
      {
         if (!IsPlaformCompatable()) return;
         Application.EnableVisualStyles();
         Application.SetCompatibleTextRenderingDefault(false);
         Run();
      }

      static void Run()
      {
         Image<Bgr, Byte> image = new Image<Bgr, byte>("lena.jpg"); //Read the files as an 8-bit Bgr image  
         Image<Gray, Byte> gray = image.Convert<Gray, Byte>(); //Convert it to Grayscale

         Stopwatch watch = Stopwatch.StartNew();
         //normalizes brightness and increases contrast of the image
         gray._EqualizeHist();

         //Read the HaarCascade objects
         HaarCascade face = new HaarCascade("haarcascade_frontalface_alt_tree.xml");
         HaarCascade eye = new HaarCascade("haarcascade_eye.xml");

         //Detect the faces  from the gray scale image and store the locations as rectangle
         //The first dimensional is the channel
         //The second dimension is the index of the rectangle in the specific channel
         MCvAvgComp[][] facesDetected = gray.DetectHaarCascade(
            face, 
            1.1, 
            10, 
            Emgu.CV.CvEnum.HAAR_DETECTION_TYPE.DO_CANNY_PRUNING, 
            new Size(20, 20));

         foreach (MCvAvgComp f in facesDetected[0])
         {
            //draw the face detected in the 0th (gray) channel with blue color
            image.Draw(f.rect, new Bgr(Color.Blue), 2);

            //Set the region of interest on the faces
            gray.ROI = f.rect;
            MCvAvgComp[][] eyesDetected = gray.DetectHaarCascade(
               eye, 
               1.1, 
               10, 
               Emgu.CV.CvEnum.HAAR_DETECTION_TYPE.DO_CANNY_PRUNING, 
               new Size(20, 20));
            gray.ROI = Rectangle.Empty;

            foreach (MCvAvgComp e in eyesDetected[0])
            {
               Rectangle eyeRect = e.rect;
               eyeRect.Offset(f.rect.X, f.rect.Y);
               image.Draw(eyeRect, new Bgr(Color.Red), 2);
            }
         }

         watch.Stop();
         //display the image 
         ImageViewer.Show(image, String.Format("Perform face and eye detection in {0} milliseconds", watch.ElapsedMilliseconds));
      }

      /// <summary>
      /// Check if both the managed and unmanaged code are compiled for the same architecture
      /// </summary>
      /// <returns>Returns true if both the managed and unmanaged code are compiled for the same architecture</returns>
      static bool IsPlaformCompatable()
      {
         int clrBitness = Marshal.SizeOf(typeof(IntPtr)) * 8;
         if (clrBitness != CvInvoke.UnmanagedCodeBitness)
         {
            MessageBox.Show(String.Format("Platform mismatched: CLR is {0} bit, C++ code is {1} bit."
               + " Please consider recompiling the executable with the same platform target as C++ code.",
               clrBitness, CvInvoke.UnmanagedCodeBitness));
            return false;
         }
         return true;
      }
   }
}

相關文章