코드 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 영상에도 원이 그려집니다.