■ HAAR를 사용해 얼굴을 검출하는 방법을 보여준다.
▶ FaceDetectionHelper.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 |
using System; using System.Collections.Generic; using System.Diagnostics; using System.Drawing; using Emgu.CV; #if !IOS using Emgu.CV.GPU; #endif using Emgu.CV.Structure; namespace TestProject { /// <summary> /// 얼굴 검출 헬퍼 /// </summary> public static class FaceDetectionHelper { //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Static //////////////////////////////////////////////////////////////////////////////// Private #region 검출하기 - Detect(image, faceClassifierFilePath, eyeClassifierFilePath, faceRectangleList, eyeRectangleList, detectionTime) /// <summary> /// 검출하기 /// </summary> /// <param name="image">이미지</param> /// <param name="faceClassifierFilePath">얼굴 분류기 파일 경로</param> /// <param name="eyeClassifierFilePath">눈 분류기 파일 경로</param> /// <param name="faceRectangleList">얼굴 사각형 리스트</param> /// <param name="eyeRectangleList">눈 사각형 리스트</param> /// <param name="detectionTime">검출 시간</param> public static void Detect(Image<Bgr, Byte> image, string faceClassifierFilePath, string eyeClassifierFilePath, List<Rectangle> faceRectangleList, List<Rectangle> eyeRectangleList, out long detectionTime) { Stopwatch stopWatch; #if !IOS if(GpuInvoke.HasCuda) { using(GpuCascadeClassifier faceGpuCascadeClassifier = new GpuCascadeClassifier(faceClassifierFilePath)) { using(GpuCascadeClassifier eyeGpuCascadeClassifier = new GpuCascadeClassifier(eyeClassifierFilePath)) { stopWatch = Stopwatch.StartNew(); using(GpuImage<Bgr, Byte> gpuImage = new GpuImage<Bgr, byte>(image)) { using(GpuImage<Gray, Byte> gpuGray = gpuImage.Convert<Gray, Byte>()) { Rectangle[] faceRectangleArray = faceGpuCascadeClassifier.DetectMultiScale(gpuGray, 1.1, 10, Size.Empty); faceRectangleList.AddRange(faceRectangleArray); foreach(Rectangle faceRectangle in faceRectangleArray) { using(GpuImage<Gray, Byte> faceGpuImage = gpuGray.GetSubRect(faceRectangle)) { using(GpuImage<Gray, Byte> cloneGpuImage = faceGpuImage.Clone()) { Rectangle[] eyeRectangleArray = eyeGpuCascadeClassifier.DetectMultiScale(cloneGpuImage, 1.1, 10, Size.Empty); foreach(Rectangle eyeRectangle in eyeRectangleArray) { Rectangle temporaryEyeRectangle = eyeRectangle; temporaryEyeRectangle.Offset(faceRectangle.X, faceRectangle.Y); eyeRectangleList.Add(temporaryEyeRectangle); } } } } } } stopWatch.Stop(); } } } else #endif { using(CascadeClassifier faceCascadeClassifier = new CascadeClassifier(faceClassifierFilePath)) { using(CascadeClassifier eyeCascadeClassifier = new CascadeClassifier(eyeClassifierFilePath)) { stopWatch = Stopwatch.StartNew(); using(Image<Gray, Byte> grayImage = image.Convert<Gray, Byte>()) { grayImage._EqualizeHist(); Rectangle[] faceRectangleArray = faceCascadeClassifier.DetectMultiScale ( grayImage, 1.1, 10, new Size(20, 20), Size.Empty ); faceRectangleList.AddRange(faceRectangleArray); foreach(Rectangle faceRectangle in faceRectangleArray) { grayImage.ROI = faceRectangle; Rectangle[] eyeRectangleArray = eyeCascadeClassifier.DetectMultiScale ( grayImage, 1.1, 10, new Size(20, 20), Size.Empty ); grayImage.ROI = Rectangle.Empty; foreach(Rectangle eyeRectangle in eyeRectangleArray) { Rectangle temporaryEyeRectangle = eyeRectangle; temporaryEyeRectangle.Offset(faceRectangle.X, faceRectangle.Y); eyeRectangleList.Add(temporaryEyeRectangle); } } } stopWatch.Stop(); } } } detectionTime = stopWatch.ElapsedMilliseconds; } #endregion } } |
▶ Program.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
using System; using System.Collections.Generic; using System.Drawing; using System.Windows.Forms; using Emgu.CV; using Emgu.CV.Structure; using Emgu.CV.UI; using Emgu.CV.GPU; namespace TestProject { /// <summary> /// 프로그램 /// </summary> static class Program { //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Static //////////////////////////////////////////////////////////////////////////////// Private #region 프로그램 시작하기 - Main() /// <summary> /// 프로그램 시작하기 /// </summary> [STAThread] private static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Image<Bgr, Byte> image = new Image<Bgr, byte>("sample.jpg"); long detectionTime; List<Rectangle> faceRectangleList = new List<Rectangle>(); List<Rectangle> eyeRectangleList = new List<Rectangle>(); FaceDetectionHelper.Detect ( image, "haarcascade_frontalface_default.xml", "haarcascade_eye.xml", faceRectangleList, eyeRectangleList, out detectionTime ); foreach(Rectangle faceRectangle in faceRectangleList) { image.Draw(faceRectangle, new Bgr(Color.Red), 1); } foreach(Rectangle eyeRectangle in eyeRectangleList) { image.Draw(eyeRectangle, new Bgr(Color.Blue), 2); } ImageViewer.Show ( image, string.Format ( "{0}를 사용해 얼굴/눈 검출 완료 : {1} 밀리초", GpuInvoke.HasCuda ? "GPU" : "CPU", detectionTime ) ); } #endregion } } |