---
title: "Face Detect"
id: "751"
type: "post"
slug: "423"
published_at: "2011-01-18T19:10:37+00:00"
modified_at: "2025-12-12T04:29:34+00:00"
url: "https://dworld.deios.kr/423/"
markdown_url: "https://dworld.deios.kr/423.md"
excerpt: "이번 시간은 MFC와 OpenCV의 기본 사용법 마지막 내용이 되겠습니다. Cam 영상을 Dialog에 뿌려주는 부분에서 기본 사용법이 끝났어야 하지만… 조금 아쉬운 관계로 더 진행해 봤죠… 저도 아직 초보단계지만, MFC와 OpenCV의 기본 사용법은 뭐 없습니다… MFC야… GUI프로그래밍을 위해서 그냥 쓴 것이고… OpenCV는..."
taxonomy_category:
  - "Study"
taxonomy_post_tag:
  - "AR"
  - "cam"
  - "MFC"
  - "opencv"
  - "VS2010"
  - "증강현실"
---

이번 시간은 MFC와 OpenCV의 기본 사용법 마지막 내용이 되겠습니다. Cam 영상을 Dialog에 뿌려주는 부분에서 기본 사용법이 끝났어야 하지만… 조금 아쉬운 관계로 더 진행해 봤죠…

저도 아직 초보단계지만, MFC와 OpenCV의 기본 사용법은 뭐 없습니다… MFC야… GUI프로그래밍을 위해서 그냥 쓴 것이고… OpenCV는 영상을 받아오고, 출력하는 부분만 하면 기본은 끝난거 아닌가요?

지금까지 “오픈소스 OpenCV를 이용한 컴퓨터 비전 실무 프로그래밍”이라는 책을 기준으로 진행해 왔는데, 뒷부분을 살펴봐도 뭐 없습니다. 가져온 영상을 OpenCV의 각종 함수들을 사용해서 내가 원하는 데로 조작해서 보여주는 것… 그 이상도 이하도 아닙니다.

자… 그럼 마지막 내용 진행해 보겠습니다. 이번 시간에는 간단하게 지난 시간에 만들었던 Dialog를 이용하겠습니다. 버튼 하나 추가하시구요~ 버튼의 ID는 “IDC_btnFaceDetect”로 하겠습니다. 당연히 이벤트 처리기도 추가해야겠죠?

OpenCV 2.1은 Camera 영상 처리에서 Callback을 사용하지 않는 관계로 혹은 제가 너무 무식해서 관련 내용을 찾지 못했거나… 불리언(Boolean)타입의 변수 하나를 잡아 flag로 사용하겠습니다.

변수 이름은 bFDisTrue로 하겠습니다. Type은 당연히 BOOL이구요, OnInitDialog에서 FALSE로 초기화 해 주는 부분까지 작성하겠습니다. 쉽게 하실 수 있으시죠?

다음은 Face Detect를 수행할 멤버 함수를 작성하겠습니다. 함수 원형은 다음과 같습니다.

```
void FaceDetect()
```

여기까지는 무난하게 하셨을거라 보고, 이번에는 “[Cam 영상 출력해보기(http://deios.kr/413)](https://dworld.deios.kr/413)
”처럼 화면에 뿌려주기 전에 FaceDetect함수를 호출할 수 있도록 수정하겠습니다.

어디를 수정해야 할 지는 잘 아시죠? 당근 OnTimer를 수정해 줘야 합니다. 다음과 같이 수정합니다.

```
void CViewDlg::OnTimer(UINT_PTR nIDEvent)

{       // TODO: 여기에 메시지 처리기 코드를 추가 및/또는 기본값을 호출합니다.

        if(1 == nIDEvent){

                cvGrabFrame( capture );

                image = cvQueryFrame( capture );

                FaceDetect();

                m_CvvImage.CopyOf(image);

                CRect viewSize;

                m_sView.GetClientRect(&viewSize);

                m_CvvImage.DrawToHDC( m_sView.GetDC()->GetSafeHdc() ,viewSize);

        }

        CDialogEx::OnTimer(nIDEvent);

}
```

IDC_btnFaceDetect 이벤트 처리기에는 bFDisTrue의 값을 TRUE로 바꿔주는 코드를 넣겠습니다. 조금 응용하면 “시작 → 중지”버튼처럼 구현 할 수 있겠죠? 이것은 각자 해보세요~ 이벤트 처리기의 코드는 생략하겠습니다. 빨리 하고 자려구요 ㅠㅠ

Face Detect함수의 코드를 보여드리겠습니다.

```
void CViewDlg::FaceDetect()

{

        if(!bFDisTrue) return;

        CvScalar colors[] =  {  CV_RGB(0,0,255), CV_RGB(0,128,255), CV_RGB(0,255,255),

                                CV_RGB(0,255,0), CV_RGB(255,128,0), CV_RGB(255,255,0),

                                CV_RGB(255,0,0), CV_RGB(255,0,255)} ;

        double scale = 2.0;

 

        IplImage *gray = cvCreateImage(cvSize(image->width, image->height), 8, 1);

        IplImage *small_img = cvCreateImage(cvSize(cvRound(image->width / scale), cvRound(image->height/scale)), 8, 1);

 

        cvCvtColor(image, gray, CV_BGR2GRAY);

        cvResize(gray, small_img, CV_INTER_LINEAR);

        cvEqualizeHist(small_img, small_img);

        if(storage) cvClearMemStorage(storage);

 

        if(cascade){

                CvSeq *faces = cvHaarDetectObjects(small_img, cascade, storage, 1.1, 2, 0, cvSize(30, 30));

 

                for (int i = 0; i < (faces ? faces->total : 0); i++){

                        CvRect *r = (CvRect *)cvGetSeqElem(faces, i);

 

                        CvPoint center;

                        int radius;

 

                        center.x = cvRound( (r->x + r->width*0.5)*scale);

                        center.y = cvRound( (r->y + r->height*0.5)*scale);

                        radius = cvRound( (r->width + r->height)*0.25*scale);

 

                        cvCircle(image, center, radius, colors[i%8], 3, 8, 0);

                }

        }

 

        cvReleaseImage(&gray);

        cvReleaseImage(&small_img);

}
```

<

p class=”HStyle0″ style=”line-height: 150%;”>

마지막으로 두 개의 멤버변수를 잡고, 초기화 하겠습니다.

멤버변수는 다음과 같습니다.

```
CvMemStorage *storage;

CvHaarClassifierCascade *cascade;
```

초기화는 당연히 OnInitDialog에서 해 줘야 겠죠? 다음과 같이 초기화합니다.

```
cascade = (CvHaarClassifierCascade *)cvLoad("haarcascade_frontalface_alt2.xml", 0, 0, 0);

storage = cvCreateMemStorage(0);
```

짜짜잔~

cfile24.uf.203234514D35E90C11EEEB.pdf

cfile25.uf.123272514D35E5700B95C4.zipcfile25.uf.143192514D35E575139482.xmlcfile9.uf.123324434DEE56BF34AD4F.xml

### 이 글 공유하기:

- [Facebook으로 공유하기 (새 창에서 열림)Facebook](https://dworld.deios.kr/423/?share=facebook)
- [X에 공유 (새 창에서 열림)X](https://dworld.deios.kr/423/?share=x)
-

### 이것이 좋아요:

좋아하기로드 중...

### *관련*

### 관련된 글:

1. [Cam 영상 출력해보기](https://dworld.deios.kr/413/)
2. [MFC – Cam 영상 출력해보기](https://dworld.deios.kr/420/)
3. [모덜리스(Modeless) Dialog로 변환하기](https://dworld.deios.kr/421/)
4. [정지영상 캡춰기능 구현](https://dworld.deios.kr/422/)

## Similar Posts

- TCP의 폭주제어에서 예약방식을 못 쓰고 피드백 기반 방식을 사용하여야 하는 이유를 설명하시오. 예약 방식의 경우 데이터 전송 중 경로상의 라우터에서 폭주 혹은 에러가 발생했을 경우 송신자는 계속 데이터를 보내게 되어 혼잡이 가중된다. 이를 해결하기 위해 피드백 방식을 사용한다.송신자는 약간의 데이터만 전송하여 도착 여부를 확인 후 점점 전송량을 늘려간다. 이처럼 네트워크의 상태에 따라 송신측에서 전송량을 조절하여야 한다…. ### 이 글 공유하기: - [Facebook으로 공유하기 (새 창에서 열림)Facebook](https://dworld.deios.kr/372/?share=facebook) - [X에 공유 (새 창에서 열림)X](https://dworld.deios.kr/372/?share=x) - ### 이것이 좋아요: 좋아하기로드 중...
- 함수종속 어떤 릴레이션 R에서 X와 Y를 의 애트리뷰트 집합의 부분집합이라 하자. X의 값 각각에 대해 시간에 관계 없이 Y의 값이 오직 하나만 연관되어 있을 때 Y는 X에 함수종속이라 하고 X →Y로 표기한다. 이 때, X를 결정자, Y를 종속자라고 한다. 제 1 정규형(1NF) 어떤 릴레이션 R에 속한 모든 도메인이 원자값만으로 되어 있다면 제 1 정규형이라고 한다. 제 2… ### 이 글 공유하기: - [Facebook으로 공유하기 (새 창에서 열림)Facebook](https://dworld.deios.kr/374/?share=facebook) - [X에 공유 (새 창에서 열림)X](https://dworld.deios.kr/374/?share=x) - ### 이것이 좋아요: 좋아하기로드 중...
- [https://dworld.deios.kr/406/](https://dworld.deios.kr/406/) 이번에는 자주 사용하는 기능인 C&P(Copy & Paste)를 구현해 보도록 하겠습니다. C&P를 구현하기 위해서는 이미지를 DIB(장치 독립 비트맵;Device Independent Bitmap)으로 변환하여 클립보드 영역에 넘겨주거나, 클립보드 영역에서 데이터를 받아오면 됩니다. 클립보드 영역으로 데이터를 넘겨주기 위하여 CopyClipBoard맴버함수, CopyToHandle 맴버 함수를 추가하여, ID_EDIT_COPY이벤트 핸들러에 등록합니다. 먼저 CopyClipBoard 맴버 함수를 Doc Class에 작성하겠습니다. 반환 형식 : void 함수 이름… ### 이 글 공유하기: - [Facebook으로 공유하기 (새 창에서 열림)Facebook](https://dworld.deios.kr/406/?share=facebook) - [X에 공유 (새 창에서 열림)X](https://dworld.deios.kr/406/?share=x) - ### 이것이 좋아요: 좋아하기로드 중...
- [https://dworld.deios.kr/419/](https://dworld.deios.kr/419/) 이번 시간에는 조금 더 재미있는 것을 해 보겠습니다. 바로 요놈입니다. 바로 HyVision System의 HVR-2000 Series입니다. 일반적인 웹캠이야 그냥 연결만 해주면 바로 써먹을 수 있었는데, 요놈은 조금 다릅니다. USB드라이버야 당연히 깔아줘야 하는거고… 별도의 SDK를 이용해서 Cam에 접근하게 됩니다. 하이비전시스템에서 HVR SDK Interface Guide를 친절하게 작성해 주셔서 별 무리 없이 실습을 진행 해 볼… ### 이 글 공유하기: - [Facebook으로 공유하기 (새 창에서 열림)Facebook](https://dworld.deios.kr/419/?share=facebook) - [X에 공유 (새 창에서 열림)X](https://dworld.deios.kr/419/?share=x) - ### 이것이 좋아요: 좋아하기로드 중...
- [https://dworld.deios.kr/424/](https://dworld.deios.kr/424/) 이전 시간까지는 처음에 만들었던 “MFC_OpenCV”라는 프로젝트를 기준으로 진행하였습니다. 하지만, 이제부터는 새 프로젝트를 만들어서 진행하는 경우가 많이 생길텐데요… 이 때마다 프로젝트 설정을 바꿔줘야 하는게 여간 귀찮은게 아닙니다… 그. 래. 서. 이번 시간에는 이러한 설정을 파일로 저장하고, 가져오는 방법에 대해서 알아보겠습니다. 일단 첨부한 OpenCV210.props 파일을 적당한 디렉토리에 다운로드 하시구요… 먼저 이 파일을 어떻게 불러오는지부터 알아보겠습니다. 먼저 VS2010실행하셔서… ### 이 글 공유하기: - [Facebook으로 공유하기 (새 창에서 열림)Facebook](https://dworld.deios.kr/424/?share=facebook) - [X에 공유 (새 창에서 열림)X](https://dworld.deios.kr/424/?share=x) - ### 이것이 좋아요: 좋아하기로드 중...
- [https://dworld.deios.kr/420/](https://dworld.deios.kr/420/) 이번 시간에는 MFC프로젝트에서 Cam 영상을 받아오는 부분을 구현해 보겠습니다. “동영상 처리” → “영상 보기”메뉴를 추가하고, 해당 메뉴를 클릭했을 때, 영상을 뿌려주는 Dialog를 띄웁니다. Dialog에서 “시작” 버튼을 클릭했을 경우 Caption이 “중지”로 바뀌고, Static 영역에 영상을 뿌려주게 만들어 보겠습니다. 먼저 사용할 다이얼로그부터 만들어야겠죠? [리소스 뷰]에서 [리소스 추가]를 선택합니다. [Dialog]가 선택된 것을 확인하고 [새로 만들기]를… ### 이 글 공유하기: - [Facebook으로 공유하기 (새 창에서 열림)Facebook](https://dworld.deios.kr/420/?share=facebook) - [X에 공유 (새 창에서 열림)X](https://dworld.deios.kr/420/?share=x) - ### 이것이 좋아요: 좋아하기로드 중...

## 12 Comments

1. scale이 클 수록 더 빨리 영상을 처리하게 됩니다. 처음엔 인터발을 (1/12)*1000주고, scale을 1.2 줬는데… 뭐 이건 영상을 볼 수가 없더군요… 그래서 scale만 2.0으로 올렸더니 어느정도 봐 줄만 합니다… [답글](#comment-258)
2. 얼굴을 잘 잡지를 못하고 벽이나 다른 곳을 잡습니다. xml 파일만 교체해도 이 코드가 실행되는지 궁금합니다. ^^ [답글](#comment-259)
  1. 정면이 아닌 측면얼굴이나, 하단에서 올려다볼때, 상단에서 올려다볼때는 인식을 하지 못합니다 ㅠㅠ 파일 이름도 haarcascade_eye_tree_eyeglasses 와 haarcascade_frontalface_alt2죠… [답글](#comment-260)
  2. 앗 haarcascade_frontalface_alt2.xml 파일은 따로 올리지 않았군요… 첨부하겠습니다~ [답글](#comment-261)

3. 그 전에 face detect 예제를 돌려보았던 차여서 haarcascade_frontalface_alt2.xml 는 있었습니다. OpenCV 1.0 예제에 있는 facedetect 와 haarcascade_frontalface_alt2.xml 파일명도 같고 소스 코드도 비슷한데 잡히는 정도가 다르네요. 1.0 예제의 코드는 안경을 쓰고 있어도 매우 잘 잡고 있기에 어떠한 차이점이 있는지 궁금하네요. Deios 님의 완성된 코드로 직접 실행해보셨을 때에는 잘 잡히시는지요? [답글](#comment-262)
  1. 네… 저도 안경을 쓰고 있는데 정면은 잘 됩니다. 스케일과 인터벌을 조정해 보세요~ [답글](#comment-263)
  2. 1.0과의 차이점은 콜백 사용여부입니다. 1.0은 콜백함수를 사용하여 OpenCV가 영상을 보여주기 전에 콜백함수를 실행하게 되고 OpenCV가 화면에 영상을 뿌려줍니다… 2.0부터인가 콜백함수를 사용할 수 없기에 일단 OpenCV로부터 영상을 받아와서 처리후 화면에 뿌려주게 됩니다… 성능 이슈는 충분히 있을 수 있죠… [답글](#comment-264)

4. 스케일과 인터벌을 바꿔보도록 하겠습니다 ㅎ [답글](#comment-265)
  1. 글 작성시엔 스케일이 2.0이였고, 제 경우엔 너무 느려서 3.0정도로 조정하니 봐줄만 했습니다. 방금 인터벌을 (1/(double)8)*1000 주고, 스케일을 5.0으로 줬는데 무리없이 잘 돌아가네요… 인터벌과 스케일 모두 작을수록 좋습니다… 벽이 잡힌다고 하시니 해당 문제는 아니겠지만 혹시나 해서 스케일과 인터벌을 조정해보라 말씀드린겁니다… 안경 쓴 상태에서 인식한 화면 올려둘께요~ 제가 사용한 코드는 본문에 첨부된 파일 그대로입니다…(스케일과 인터벌만 수정) [답글](#comment-266)

5. 성실한 답변 감사합니다. 참고하겠습니다 ^^ [답글](#comment-267)
6. 좋은 예시 감사하고 . 초보라서 그런데..detection된 원 모양을 직사각형이나 정사각형으로 나타내게 할려면 어떤 함수를 써야되나요? 답변 부탁드립니다. [답글](#comment-268)
7. 올려주신 글을 보고 공부 많이 하고있습니다. 감사합니다. 올려주신 예제를 따라하고 있는데요. 얼굴 검출이 안되요.ㅠ 그래서 if(cascade)아래 AfxMessageBox(_T(“1”) )로 들어가는지 봤더니 안들어가더군요. 왜그런걸까요? [답글](#comment-269)

### 댓글 남기기[응답 취소](/423/?t=1784844129#respond)
