05-11 08:25
Notice
Recent Posts
Recent Comments
관리 메뉴

Scientific Computing & Data Science

[Programming / OpenCV] Face Recognition(안면 인식) 본문

Programming/OpenCV

[Programming / OpenCV] Face Recognition(안면 인식)

cinema4dr12 2015. 8. 9. 20:14

이번 글에서는 OpenCV에서 Webcam을 통해 실시간으로 얼굴을 인식하는 방법에 대하여 알아보도록 하겠습니다. 튜토리얼 방식으로 진행되며 아래의 절차를 따라 테스트 해 보시기 바랍니다.

Tutorial

1.  Webcam으로 Frame Capture를 합니다.


1
2
3
4
5
6
7
8
// open the default camera
cv::VideoCapture cap( 0 );
 
// check if we succeeded
if!cap.isOpened() ) {
    std::cerr << "Could not open camera" << std::endl;
    return -1;
}
cs



* NOTE: Webcam을 이용한 Frame Capture에 대한 자세한 내용은 다음 링크를 참고시기 바랍니다:

http://cinema4dr12.tistory.com/entry/OpenCV-WebCam-Frame-Capture


2.  Webcam 화면을 띄울 Window를 생성합니다.


1
2
// create a window
cv::namedWindow( "webcam"1 );
cs


3.  OpenCV의 Cascade Classifier 인스턴스를 하나 생성하고, OpenCV가 제공하는 샘플 Haar Cascade 데이터를 로딩합니다.


1
2
3
4
// face detection configuration
cv::CascadeClassifier face_classifier;
 
face_classifier.load( "{YOUR_OPENCV_PATH}/data/haarcascades/haarcascade_frontalface_default.xml" );
cs


OpenCV가 제공하는 샘플 데이터는 OpenCV를 다운로드 한 폴더의 sources/data/ 경로에 있습니다.


본 예제에서는 안면 인식을 위해 {OPENCV_ROOT}/sources/data/haarcascades/haarcascade_frontalface_default.xml 데이터를 사용하였습니다. Haarcascade의 다양한 데이터 파일을 테스트 해보는 것도 재미있을 것으로 생각됩니다.


4.  OpenCV의 Mat 인스턴스를 생성한다.


1
cv::Mat frame;
cs


5.  연속적으로 Frame Capture를 하기 위해 무한 For Loop문을 작성한다.


1
2
3
for( ; ; ) {
    ...
}
cs


또는 While 문으로 작성하여도 됩니다.


1
2
3
whiletrue ) {
    ...
}
cs


6.  Webcam으로 들어오는 Frame이 유효한 지 검사를 위한 flag를 선언합니다.


1
bool frame_valid = true;
cs


7.  Webcam으로부터 새로운 Image Frame을 얻어오고 실패 시 예외처리를 합니다.


1
2
3
4
5
6
7
8
9
10
11
try {
 
    // get a new frame from webcam
    cap >> frame;
 
catch( cv::Exception& e ) {
 
    std::cerr << "Exception occurred. Ignoring frame... " << e.err << std::endl;
    frame_valid = false;
 
}
cs


8.  다음  연산들을 통해 안면을 인식하고 인식된 위치에 사각형을 그려 표시합니다.

  • 컬러 이미지로 얻은 Image Frame을 Grayscale로 변환합니다.

  • Grayscale로 변환된 이미지의 Histogram을 얻습니다.

  • detectMultiScale() 함수로 얼굴의 위치와 영역을 탐색합니다.

  • 탐색된 얼굴의 위치와 영역에 대하여 Webcam의 Image Frame 상에 직사각형을 그립니다.

  • 생성된 Window에 이미지를 띄웁니다.


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
// convert captured frame to gray scale & equalize
cv::Mat grayframe;
cv::cvtColor( frame, grayframe, CV_BGR2GRAY );
cv::equalizeHist( grayframe, grayframe );
 
// a vector array to store the face found
std::vector<cv::Rect> faces;
 
face_classifier.detectMultiScale(grayframe, faces,
    1.1// increase search scale by 10% each pass
    3,   // merge groups of three detections
    CV_HAAR_FIND_BIGGEST_OBJECT|CV_HAAR_SCALE_IMAGE,
    cv::Size( 3030 )
);
 
// draw the results
forint i = 0 ; i < faces.size() ; i++ ) {
    cv::Point lb( faces[i].x + faces[i].width, faces[i].y + faces[i].height );
    cv::Point tr( faces[i].x, faces[i].y );
 
    cv::rectangle( frame, lb, tr, cv::Scalar( 02550 ), 340 );
}
 
// print the output
cv::imshow( "webcam", frame );
cs


Example Code/ C++

전체적인 예제 코드는 다음과 같습니다:


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
#include <iostream>
#include <opencv2/opencv.hpp>
 
#include <stdlib.h>
#include <stdio.h>
 
using namespace std;
using namespace cv;
 
 
/* @ function main */
int main( int argc, char *argv[] )
{
    // open the default camera
    cv::VideoCapture cap( 0 );
  
    // check if we succeeded
    if!cap.isOpened() ) {
        std::cerr << "Could not open camera" << std::endl;
        return -1;
    }
  
    // create a window
    cv::namedWindow( "webcam"1 );
  
    // face detection configuration
    cv::CascadeClassifier face_classifier;
 
    face_classifier.load( "{YOUR_OPENCV_PATH}/data/haarcascades/haarcascade_frontalface_default.xml" );
  
    cv::Mat frame;
 
    for( ; ; ) {
        bool frame_valid = true;
  
        try {
 
            // get a new frame from webcam
            cap >> frame;
 
        } catch( cv::Exception& e ) {
 
            std::cerr << "Exception occurred. Ignoring frame... " << e.err << std::endl;
            frame_valid = false;
 
        }
  
        if( frame_valid ) {
            try {
                // convert captured frame to gray scale & equalize
                cv::Mat grayframe;
                cv::cvtColor( frame, grayframe, CV_BGR2GRAY );
                cv::equalizeHist( grayframe, grayframe );
  
                // -------------------------------------------------------------
                // face detection routine
  
                // a vector array to store the face found
                std::vector<cv::Rect> faces;
  
                face_classifier.detectMultiScale( grayframe, faces,
                    1.1// increase search scale by 10% each pass
                    3,   // merge groups of three detections
                    CV_HAAR_FIND_BIGGEST_OBJECT|CV_HAAR_SCALE_IMAGE,
                    cv::Size( 3030 )
                );
  
                // -------------------------------------------------------------
                // draw the results
                forint i = 0 ; i < faces.size() ; i++ ) {
                    cv::Point lb( faces[i].x + faces[i].width, faces[i].y + faces[i].height );
                    cv::Point tr( faces[i].x, faces[i].y );
  
                    cv::rectangle( frame, lb, tr, cv::Scalar( 02550 ), 340 );
                }
  
                // print the output
                cv::imshow( "webcam", frame );
  
            } catch( cv::Exception& e ) {
                std::cerr << "Exception occurred. Ignoring frame... " << e.err << std::endl;
            }
        }
 
        if ( cv::waitKey(30>= 0 ) break;
    }
  
    // VideoCapture automatically deallocate camera object
    return 0;
}
cs


Result


Example Code/ Python

Face Detection을 위한 Python 예제 코드는 다음과 같으며, Eye Detection도 추가하였습니다.


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
import cv2
 
faceCascPath = "haarcascade_frontalface_default.xml"
eyeCascPath = "haarcascade_eye.xml"
 
faceCascade = cv2.CascadeClassifier(faceCascPath)
eye_cascade = cv2.CascadeClassifier(eyeCascPath)
 
video_capture = cv2.VideoCapture(0)
 
while True:
    # Capture frame-by-frame
    ret, frame = video_capture.read()
 
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
 
    faces = faceCascade.detectMultiScale(
        gray,
        scaleFactor=1.1,
        minNeighbors=5,
        minSize=(3030),
        flags = cv2.CASCADE_SCALE_IMAGE
    )
 
    # Draw a rectangle around the faces
    for (x, y, w, h) in faces:
        cv2.rectangle(frame, (x, y), (x+w, y+h), (02550), 2)
        
        # eye
        roi_gray = gray[y:y+h, x:x+w]
        roi_color = frame[y:y+h, x:x+w]
        
        eyes = eye_cascade.detectMultiScale(roi_gray)
        for (ex,ey,ew,eh) in eyes:
            cv2.rectangle(roi_color,(ex,ey),(ex+ew,ey+eh),(0,255,0),2)
 
    # Display the resulting frame
    cv2.imshow('Video', frame)
 
    if cv2.waitKey(1& 0xFF == ord('q'):
        # When everything is done, release the capture
        video_capture.release()
        cv2.waitKey(1)
        cv2.destroyAllWindows()
        break
cs



Comments