본문 바로가기
2_ 바삭바삭 프로그래밍/C# and Visual C++

[C#] OpenCV를 이용한 얼굴검출(Haar) 알고리즘

by 준환이형님_ 2013. 3. 16.


OpenCV는 오픈소스 영상처리 라이브러리입니다.

현업에서 사용하는 다양한 유료 라이브러리에 비해 기능이나 정확성, 처리속도 면에서 아쉬운 점이 없지는 않겠지만,

코드가 공개되어 언제든지 편리하게 사용할 수 있게 해 준다는 건 개발자에게 매우 고마운 일인 것 같습니다

(얼굴을 좀 못잡긴 하죠? ㅋㅋ)

 


학부때 소개했다가 파장을 불러일으켰던 (교수님의 눈빛을 흔들리게 했던) 그 라이브러리!!

그중에서도 얼굴 검출 Haar알고리즘을 사용하기 쉽도록 소스만 올립니다(Dll링크 등의 환경설정이 필요없음. 이미지 경로만 수정해 주세요)


OpenCV예제.zip

 

OpenCV를 이용한 영상 처리를 해보시고 싶으신 분은 오픈CV Sharp 홈페이지를 참조하세요

 

https://code.google.com/p/opencvsharp/

 

 

라이브러리는 버젼이 많으나 환경설정도 어렵고 호환이 안되는 경우가 많은데 아래 버젼(dll)이 저는 잘 되었구요 

 

C#_OpenCv설정파일.alz

 

 

 

자세한 설정과 구현방법은 들로네 (tramper2)님 블로그를 참조하세요. 잘 정리 되어 있습니다.


http://blog.naver.com/tramper2?Redirect=Log&logNo=100070916543

 

 

 

전체 소스는 OpenCV 샘플코드를 조금 수정하였습니다.

 

 

using System;
using System.Windows.Forms;
using OpenCvSharp;

namespace CSample
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

    //아래 경로를 수정 해 주세요

            IplImage img = new IplImage("c:\\c.jpg", LoadMode.Color);

            Face fac = new Face();
            IplImage imgHarr = fac.FaceDetect(img);

            pictureBoxIpl2.ImageIpl = imgHarr;

            return;
        }

        class Face : IDisposable
        {
            IplImage FindFace;
            public IplImage FaceDetect(IplImage src)
            {
                // CvHaarClassifierCascade, cvHaarDetectObjects
                // 얼굴을 검출하기 위해서 Haar 분류기의 캐스케이드를 이용한다
                CvColor[] colors = new CvColor[]{
                new CvColor(0,0,255),
                new CvColor(0,128,255),
                new CvColor(0,255,255),
                new CvColor(0,255,0),
                new CvColor(255,128,0),
                new CvColor(255,255,0),
                new CvColor(255,0,0),
                new CvColor(255,0,255),
            };
                const double scale = 1.04;
                const double scaleFactor = 1.139;
                const int minNeighbors = 2;
                using (IplImage img = src.Clone())
                using (IplImage smallImg = new IplImage(new CvSize(Cv.Round(img.Width / scale), Cv.Round(img.Height / scale)), BitDepth.U8, 1))
                {
                    // 얼굴 검출용의 화상의 생성
                    using (IplImage gray = new IplImage(img.Size, BitDepth.U8, 1))
                    {
                        Cv.CvtColor(img, gray, ColorConversion.BgrToGray);
                        Cv.Resize(gray, smallImg, Interpolation.Linear);
                        Cv.EqualizeHist(smallImg, smallImg);
                    }
                    using (CvHaarClassifierCascade cascade = CvHaarClassifierCascade.FromFile(Application.StartupPath + "\\" + "haarcascade_frontalface_alt.xml"))

                    using (CvMemStorage storage = new CvMemStorage())
                    {
                        storage.Clear();
                        // 얼굴의 검출
                        CvSeq<CvAvgComp> faces = Cv.HaarDetectObjects(smallImg, cascade, storage, scaleFactor, minNeighbors, 0, new CvSize(30, 30));
                        // 검출한 얼굴에 원을 그린다
                        for (int i = 0; i < faces.Total; i++)
                        {
                            CvRect r = faces[i].Value.Rect;
                            CvPoint center = new CvPoint
                            {
                                X = Cv.Round((r.X + r.Width * 0.5) * scale),
                                Y = Cv.Round((r.Y + r.Height * 0.5) * scale)
                            };
                            int radius = Cv.Round((r.Width + r.Height) * 0.5 * scale);
                            img.Circle(center, radius, colors[i % 8], 15, LineType.AntiAlias, 0);
                        }
                    }
                    FindFace = img.Clone();
                    return FindFace;
                }
            }

            public void Dispose()
            {
                if (FindFace != null) FindFace.Dispose();
            }
        }
    }
}