Computer >> 컴퓨터 >  >> 프로그래밍 >> C++

C++와 OpenCV로 웹캠 영상에서 실시간 얼굴 검출하는 방법


실시간 얼굴 검출(real-time face detection)은 정지 이미지에서 얼굴을 찾는 방식과 기본 원리가 같습니다. 결정적인 차이점은 실시간 검출에서는 컴퓨터에 연결된 카메라로부터 비디오 스트림을 계속해서 입력받아야 한다는 점입니다. 이 프로그램에서는 VideoCapture() 함수를 사용하는데, 이 함수는 카메라로부터 영상을 캡처하여 프레임 단위로 임시 행렬(Matrix)에 저장합니다. 여기서는 기본 웹캠(0번 카메라)으로부터 영상을 받아 프레임을 'video_stream' 행렬에 담습니다.

다음 프로그램은 사람의 얼굴을 실시간으로 검출합니다.

예제 코드

#include<iostream>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
//'rectangle()' 함수의 정의가 포함된 헤더//
#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++){ //검출된 얼굴의 위치 확인
            Mat faceROI = video_stream(faces[i]);//검출된 얼굴 영역을 별도의 행렬에 저장//
            int x = faces[i].x;//얼굴 사각형 시작점의 x 좌표//
            int y = faces[i].y;//얼굴 사각형 시작점의 y 좌표//
            int h = y + faces[i].height;//사각형의 높이 계산//
            int w = x + faces[i].width;//사각형의 너비 계산//
            rectangle(video_stream, Point(x, y), Point(w, h), Scalar(255, 0, 255), 2, 8, 0);//얼굴 주위에 사각형 그리기//
        }
        imshow("Face Detection", video_stream);
        //검출 결과 화면에 표시//
        if (waitKey(10) == 27){ //각 프레임당 대기 시간은 10밀리초//
            break;
        }
    }
    return 0;
}

주요 코드 설명

VideoCapture real_time(0)은 시스템의 기본 카메라(인덱스 0)를 열어 영상 스트림을 가져옵니다. 외부 USB 카메라를 사용하려면 인덱스를 1, 2 등으로 변경하면 됩니다.

detectMultiScale() 함수는 Haar Cascade 분류기를 이용해 이미지 안에서 얼굴을 다양한 크기로 검출합니다. 각 매개변수의 의미는 다음과 같습니다.

  • scaleFactor(1.1): 이미지 피라미드를 단계별로 축소하는 비율입니다. 값이 작을수록 검출 정밀도는 높아지지만 처리 속도가 느려집니다.
  • minNeighbors(4): 후보 영역이 최종 얼굴로 인정되기 위해 필요한 이웃 검출 횟수입니다. 값이 클수록 오탐(false positive)이 줄어듭니다.
  • CASCADE_SCALE_IMAGE: 이미지 크기를 점진적으로 줄여가며 검출하도록 지정하는 플래그입니다.
  • Size(30, 30): 검출할 얼굴의 최소 크기로, 이보다 작은 영역은 무시됩니다.

검출된 얼굴의 좌표(x, y)와 크기(width, height)를 이용해 rectangle() 함수로 얼굴 영역에 분홍색(Scalar(255, 0, 255)) 사각형을 그립니다. 마지막으로 waitKey(10)은 각 프레임 사이에 10밀리초를 대기하며, ESC 키(ASCII 코드 27)가 눌리면 무한 루프를 빠져나와 프로그램이 종료됩니다.

실행 결과

프로그램을 실행하면 "Face Detection"이라는 제목의 윈도우에 웹캠 영상이 실시간으로 출력되고, 카메라에 잡힌 사람의 얼굴 위에 분홍색 사각형이 표시됩니다.

C++와 OpenCV로 웹캠 영상에서 실시간 얼굴 검출하는 방법