개요
이번 튜토리얼에서는 OpenCV를 활용해 웹캠 영상에서 실시간으로 얼굴을 추적하는 방법을 알아보겠습니다. 이전에 다룬 얼굴 검출 프로그램과 전반적인 구조는 동일하지만, 두 가지 차이점이 있습니다.
- 얼굴 영역을 표시할 때 사각형(rectangle) 대신 타원(ellipse)을 사용합니다.
cout문을 추가하여 감지된 얼굴의 중심 좌표를 콘솔 창에 출력합니다.
예제 코드
다음은 카메라 영상에서 사람의 얼굴을 실시간으로 감지하고 추적하는 완전한 C++ 프로그램입니다.
#include<iostream>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
//'ellipse()' 함수의 정의가 포함된 헤더//
#include<opencv2/objdetect/objdetect.hpp>
//CascadeClassifier 클래스의 정의가 포함된 헤더//
#include<string>
using namespace std;
using namespace cv;
int main(int argc, char** argv) {
Mat video_stream;//비디오 스트림의 프레임을 저장할 행렬 선언//
VideoCapture real_time(0);//기본 웹캠에서 비디오 캡처//
namedWindow("Face Detection");//결과를 표시할 윈도우 생성//
string trained_classifier_location = "C:/opencv/sources/data/haarcascades/haarcascade_frontalface_alt.xml";//학습된 XML 분류기 파일의 경로를 문자열로 지정//
CascadeClassifier faceDetector;//CascadeClassifier 클래스의 객체 'faceDetector' 선언//
faceDetector.load(trained_classifier_location);//객체에 학습된 XML 분류기 로드//
vector<Rect>faces;//검출된 얼굴 영역을 저장할 Rect 벡터 선언//
while (true) {
real_time.read(video_stream);//카메라에서 프레임을 읽어 'video_stream' 행렬에 저장//
faceDetector.detectMultiScale(video_stream, faces, 1.1, 4, CASCADE_SCALE_IMAGE, Size(30, 30));//'video_stream' 행렬에서 얼굴 검출//
for (int i = 0; i < faces.size(); i++){ //검출된 각 얼굴에 대해 반복//
Point center(faces[i].x + faces[i].width * 0.5, faces[i].y + faces[i].height * 0.5);//얼굴 영역의 중심 좌표 계산//
ellipse(video_stream, center, Size(faces[i].width * 0.5, faces[i].height * 0.5), 0, 0, 360, Scalar(255, 0, 255), 4, 8, 0);//얼굴 위에 타원 그리기//
int horizontal = (faces[i].x + faces[i].width * 0.5);//좌표의 수평(x) 값 계산//
int vertical = (faces[i].y + faces[i].height * 0.5);//좌표의 수직(y) 값 계산//
cout << "Position of the face is:" << "(" << horizontal << "," << vertical << ")" << endl;
//콘솔 창에 얼굴의 현재 위치 출력//
}
imshow("Face Detection", video_stream);
//감지된 얼굴이 표시된 영상 출력//
if (waitKey(10) == 27){ //프레임당 대기 시간은 10밀리초, ESC 키 입력 시 종료//
break;
}
}
return 0;
}
코드 핵심 설명
1. Haar Cascade 분류기 로드
CascadeClassifier 객체에 OpenCV에 기본 제공되는 학습 데이터 파일인 haarcascade_frontalface_alt.xml을 로드합니다. 이 파일은 정면 얼굴을 검출하도록 미리 학습된 Haar 특징 기반 분류기입니다. OpenCV 설치 경로의 sources/data/haarcascades 폴더에서 찾을 수 있습니다.
2. detectMultiScale()로 얼굴 검출
detectMultiScale() 함수는 입력 영상에서 여러 크기의 얼굴을 동시에 검출합니다. 주요 매개변수는 다음과 같습니다.
- 1.1: 이미지 피라미드 축소 비율(scale factor)
- 4: 후보 영역이 유지되어야 하는 최소 인접 사각형 수(minNeighbors)
- Size(30, 30): 검출 대상의 최소 크기
3. 타원 그리기와 좌표 출력
검출된 각 얼굴 영역(Rect)의 폭과 높이에 0.5를 곱해 중심점을 구한 뒤, ellipse() 함수로 자홍색(Magenta) 타원을 그립니다. 동시에 중심 좌표의 x, y 값을 cout으로 콘솔에 출력하여 얼굴의 실시간 위치를 확인할 수 있습니다.
참고: 원본 코드에서는 detectMultiScale()이 real_time.read()보다 먼저 호출되어 첫 반복에서 빈 행렬을 검사하게 됩니다. 안정적인 동작을 위해 위 예제에서는 프레임을 먼저 읽은 뒤 검출하도록 순서를 조정했습니다. 또한 y 좌표 계산 시 width 대신 height를 사용하는 것이 올바릅니다.
실행 결과
프로그램을 실행하면 웹캠 영상에 나타나는 얼굴마다 자홍색 타원이 실시간으로 표시되며, 얼굴이 움직이면 타원과 콘솔에 출력되는 좌표값도 함께 변합니다. ESC 키(ASCII 코드 27)를 누르면 프로그램이 종료됩니다.

