더북(TheBook)

코드 13-3의 detect_face() 함수에 소스 코드를 추가하여, 검출된 얼굴 안에서 눈을 검출하는 기능을 만들어 보겠습니다. 눈을 검출하기 위해서는 먼저 얼굴을 검출하고, 얼굴 영역 안에서만 눈을 검출하는 것이 효율적입니다. 눈 검출을 위해 OpenCV가 제공하는 XML 파일 중 haarcascade_eye.xml 파일을 사용할 것이며, 이 파일을 미리 프로젝트 폴더에 복사해야 합니다. 입력 영상에서 얼굴을 찾은 후, 눈 위치까지 찾는 예제 프로그램 소스 코드를 코드 13-4에 나타냈습니다. 코드 13-4의 detect_eyes() 함수의 앞부분은 코드 13-3의 detect_face() 함수와 거의 동일하고, 얼굴을 찾은 후에 눈을 찾고 눈 위치에 파란색 원을 그리는 코드가 추가되어 있습니다. 코드 13-4의 detect_eyes() 함수가 정의된 소스 코드 파일과 사용된 영상 파일은 내려받은 예제 파일 중 ch13/cascade 프로젝트 폴더에서 확인할 수 있습니다.

코드 13-4 눈 검출 예제 프로그램 [ch13/cascade]

01    void detect_eyes()
02    {
03        Mat src = imread("kids.png");
04     
05        if (src.empty()) {
06            cerr << "Image load failed!" << endl;
07            return;
08        }
09     
10        CascadeClassifier face_classifier("haarcascade_frontalface_default.xml");
11        CascadeClassifier eye_classifier("haarcascade_eye.xml");
12     
13        if (face_classifier.empty() || eye_classifier.empty()) {
14            cerr << "XML load failed!" << endl;
15            return;
16        }
17     
18        vector<Rect> faces;
19        face_classifier.detectMultiScale(src, faces);
20     
21        for (Rect face : faces) {
22            rectangle(src, face, Scalar(255, 0, 255), 2);
23     
24            Mat faceROI = src(face);
25            vector<Rect> eyes;
26            eye_classifier.detectMultiScale(faceROI, eyes);
27     
28            for (Rect eye : eyes) {
29                Point center(eye.x + eye.width / 2, eye.y + eye.height / 2);
30                circle(faceROI, center, eye.width / 2, Scalar(255, 0, 0), 2, LINE_AA);
31            }
32        }
33     
34        imshow("src", src);
35     
36        waitKey(0);
37        destroyAllWindows();
38    }

 

11행 눈 검출을 위해 haarcascade_eye.xml 파일을 사용하는 CascadeClassifier 객체를 생성합니다.

24행 입력 영상에서 검출한 사각형 얼굴 영역의 부분 영상을 추출하여 faceROI에 저장합니다.

25~26행 faceROI 영상에서 눈을 검출합니다.

28~31행 검출한 눈의 중앙에 파란색 원을 그립니다. faceROI 영상은 src 영상의 부분 영상을 참조하므로 faceROI에 원을 그리면 src 영상에도 원이 그려집니다.