using System; using System.Collections.Generic; using System.Linq; using System.Text; using OpenCvSharp; using System.Drawing; namespace MathPirate.AlternativeInputDevices.FacialRecognition { public static class DetectFaces { private static CvHaarClassifierCascade _classifierCascade; private static CvMemStorage _memStorage; //YAY! Hardcoded paths are awesome! private static string _classifierFile = @"E:\svn\Projects\AlternativeInputDevices\FacialRecognition\Data\haarcascade_frontalface_alt2.xml"; static DetectFaces() { //Workaround for crashing bug while loading classifier. IplImage fakeImage = new IplImage(100, 100, BitDepth.U8, 1); fakeImage.Erode(fakeImage); fakeImage.Dispose(); _classifierCascade = CvHaarClassifierCascade.FromFile(_classifierFile); _memStorage = new CvMemStorage(0); } public static Rectangle[] Detect(IplImage image) { CvSeq sequence = _classifierCascade.HaarDetectObjects(image, _memStorage, 1.2, 30, HaarDetectionType.DoCannyPruning, new CvSize(40, 40)); List faces = new List(); for (int i = 0; i < sequence.Total; i++) { CvRect? rect = sequence.GetSeqElem(i); if(!rect.HasValue) { continue; } CvRect rectValue = rect.Value; Rectangle rectangle = new Rectangle(rectValue.X, rectValue.Y, rectValue.Width, rectValue.Height); faces.Add(rectangle); } return faces.ToArray(); } public static Rectangle[] Detect(Bitmap bmp) { IplImage image = IplImage.FromBitmap(bmp); Rectangle[] faces = Detect(image); image.Dispose(); return faces; } public static Bitmap[] ExtractFaces(Rectangle[] faces, Bitmap bmp) { List faceBitmaps = new List(); foreach (Rectangle faceRect in faces) { Bitmap newFace = new Bitmap(faceRect.Width, faceRect.Height); Graphics newFaceGraphics = Graphics.FromImage(newFace); newFaceGraphics.DrawImage(bmp, new Rectangle(Point.Empty, faceRect.Size), faceRect, GraphicsUnit.Pixel); newFaceGraphics.Dispose(); faceBitmaps.Add(newFace); } return faceBitmaps.ToArray(); } } }