이 글에서는 OpenCV를 이용해 영상 속에서 눈을 검출하는 방법을 알아보겠습니다. 눈 검출에는 'C:/opencv/sources/data/haarcascades' 경로에 포함된 haarcascade_eye.xml 분류기를 사용하며, 얼굴 검출에는 haarcascade_frontalface_alt.xml 분류기를 함께 활용합니다. 먼저 프로그램에 반드시 포함해야 할 헤더 파일들을 살펴보겠습니다.
필수 헤더 파일
- <iostream> : C++ 프로그래밍 언어의 표준 입출력 헤더입니다.
- highgui : 이미지 읽기·쓰기 및 사용자 인터페이스(UI) 관련 기능이 정의되어 있습니다.
- imgproc : 이미지 품질 향상을 위한 다양한 이미지 처리 기능을 제공합니다.
- objdetect : 얼굴, 눈과 같은 객체를 검출하는 데 필요한 기능이 포함되어 있습니다.
다음 프로그램은 OpenCV에서 눈을 검출하고 추적하는 전체 과정을 보여줍니다. 카메라에서 영상을 받아 먼저 얼굴을 찾고, 해당 얼굴 영역 내부에서 눈을 추가로 검출하여 화면에 표시합니다.
예제 코드
#include<iostream>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2/objdetect/objdetect.hpp>
using namespace cv;
using namespace std;
int main() {
Mat frame;//비디오 프레임을 저장할 행렬 선언//
namedWindow("Detect");//결과를 보여줄 윈도우 생성//
VideoCapture image(0);//기본 카메라에서 영상 캡처//
if (!image.isOpened()){ //영상 소스를 찾지 못한 경우 에러 메시지 출력//
cout << "Couldn't load video from the source.Make sure your camera is working properly." << endl;
system("pause");
return 0;
}
double height = image.set(CAP_PROP_FRAME_HEIGHT, 480);//각 프레임의 높이 설정//
double width = image.set(CAP_PROP_FRAME_WIDTH, 640);//각 프레임의 너비 설정//
CascadeClassifier face_cascade, eyes_cascade;//CascadeClassifier 객체 선언//
face_cascade.load("C:/opencv/sources/data/haarcascades/haarcascade_frontalface_alt.xml");//얼굴 검출용 캐스케이드 분류기 로드//
eyes_cascade.load("C:/opencv/sources/data/haarcascades/haarcascade_eye.xml");//눈 검출용 캐스케이드 분류기 로드//
while (true) {
bool temp = image.read(frame);//소스에서 프레임을 읽어 frame 행렬에 저장//
vector<Rect>faces;//faces 벡터 선언//
face_cascade.detectMultiScale(frame, faces, 1.1, 2, 0 | CASCADE_SCALE_IMAGE, Size(100, 100));//얼굴 검출//
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(frame, center, Size(faces[i].width * 0.5, faces[i].height * 0.5), 0, 0, 360, Scalar(255, 0, 255), 4, 8, 0);//얼굴 위에 타원 그리기//
Mat faceROI = frame(faces[i]);//얼굴 영역을 눈 검출용 관심 영역(ROI)으로 지정//
vector<Rect>eyes;//eyes 벡터 선언//
eyes_cascade.detectMultiScale(faceROI, eyes, 1.1, 2, 0 | CASCADE_SCALE_IMAGE, Size(5, 5));//각 얼굴 영역에서 눈 검출//
for (size_t j = 0; j < eyes.size(); j++){ //검출된 눈 위치 처리//
Point center(faces[i].x + eyes[j].x + eyes[j].width * 0.5, faces[i].y + eyes[j].y + eyes[j].height * 0.5);//양쪽 눈의 중심 좌표 계산//
int radius = cvRound((eyes[j].width + eyes[j].height) * 0.25);//눈을 감싸는 원의 반지름 계산//
circle(frame, center, radius, Scalar(255, 0, 0), 4, 8, 0);//양쪽 눈 주위에 원 그리기//
}
}
imshow("Detect", frame);//'Detect' 윈도우에 결과 표시//
if (waitKey(30) == 27){ //프레임당 대기 시간 30밀리초, ESC 키 입력 시 종료//
break;
}
}
return 0;
}
코드 동작 흐름
- 카메라 연결 : VideoCapture 객체로 기본 카메라(인덱스 0)에서 영상을 받아옵니다. 카메라가 정상적으로 열리지 않으면 에러 메시지를 출력하고 프로그램을 종료합니다.
- 프레임 크기 설정 : CAP_PROP_FRAME_HEIGHT와 CAP_PROP_FRAME_WIDTH 속성을 이용해 각 프레임을 480×640 크기로 조정합니다.
- 분류기 로드 : CascadeClassifier 객체 두 개를 생성해 얼굴 검출용과 눈 검출용 Haar Cascade XML 파일을 각각 불러옵니다.
- 얼굴 검출 : detectMultiScale() 함수로 프레임 전체에서 얼굴을 찾고, 자홍색 타원으로 표시합니다.
- 눈 검출 : 검출된 각 얼굴 영역을 관심 영역(ROI)으로 지정한 뒤 다시 detectMultiScale()을 호출해 눈을 찾고, 파란색 원으로 둘러쌉니다.
- 결과 출력 및 종료 : 'Detect' 창에 결과를 실시간으로 표시하며, ESC 키(ASCII 코드 27)를 누르면 프로그램이 종료됩니다.
실행 결과
