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

C++와 OpenCV로 이미지에서 가장 큰 얼굴만 감지하는 방법


개요

이 튜토리얼에서는 OpenCV를 사용해 이미지 속 여러 얼굴 중 가장 큰 얼굴 하나만 검출하는 방법을 알아봅니다. 기본적인 얼굴 검출 절차는 이전 튜토리얼과 동일하지만, 여기서는 추가로 Rect 구조체와 for 반복문을 활용해 화면에서 가장 큰 얼굴 영역을 찾아낸다는 점이 다릅니다.

핵심 함수 형식

Mat faceROI = image_with_humanface(maxRect)

maxRect에는 이미지에서 발견된 가장 큰 얼굴의 위치와 크기(면적) 정보가 담겨 있습니다. 위 한 줄의 코드는 원본 이미지에서 maxRect에 저장된 위치와 크기에 해당하는 영역, 즉 가장 큰 얼굴이 있는 부분을 잘라내어(crop) faceROI 행렬에 저장하는 역할을 합니다.

아래 프로그램은 정지 이미지에서 가장 큰 얼굴을 검출하는 전체 예제입니다.

예제 코드

#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 image_with_humanface;//사람 얼굴이 담긴 이미지를 불러올 행렬 선언//
    image_with_humanface = imread("person.jpg");//사람 얼굴이 포함된 이미지 로드//
    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;//'faces'라는 이름의 사각형(Rect) 벡터 선언//
    faceDetector.detectMultiScale(image_with_humanface, faces, 1.1, 4, CASCADE_FIND_BIGGEST_OBJECT);//'image_with_humanface' 행렬에서 얼굴 검출//
    Rect maxRect;//사각형 선언. 기본 크기는 0픽셀//
    for (int i = 0; i < faces.size(); i++){ //가장 큰 얼굴을 찾기 위한 for 반복문 시작//
        if (faces[i].area() > maxRect.area()){ //각 얼굴의 면적을 계산해 maxRect의 면적과 비교//
            maxRect = faces[i];//가장 큰 얼굴에 해당하는 사각형을 maxRect에 저장//
        }
    }
    for (size_t i = 0; i < faces.size(); i++){ //얼굴 주위에 사각형을 그리기 위한 반복문//
        Mat faceROI = image_with_humanface(maxRect);//maxRect와 같은 크기의 행렬에 얼굴 영역 저장//
        int x = maxRect.x;//얼굴 사각형 시작점의 x 좌표 값//
        int y = maxRect.y;//얼굴 사각형 시작점의 y 좌표 값//
        int h = y + maxRect.height;//사각형의 높이 계산//
        int w = x + maxRect.width;//사각형의 너비 계산//
        rectangle(image_with_humanface, Point(x, y), Point(w, h), Scalar(255, 0, 255), 3, 6, 0);//가장 큰 얼굴 주위에 사각형 그리기//
    }
    imshow("Face Detection",image_with_humanface);//가장 큰 얼굴 표시//
    waitKey(0);//키 입력이 있을 때까지 대기한 후 프로그램 종료
    return 0;
}

코드 설명

  1. 분류기 준비: Haar Cascade 학습 파일(haarcascade_frontalface_alt.xml)의 경로를 문자열로 지정한 뒤, CascadeClassifier 객체에 로드합니다.
  2. 얼굴 검출: detectMultiScale() 함수가 이미지에서 얼굴 후보들을 검출하여 vector<Rect> 타입의 faces 벡터에 저장합니다. 필요에 따라 CASCADE_FIND_BIGGEST_OBJECT 플래그를 함께 사용할 수 있습니다.
  3. 최대 영역 찾기: 첫 번째 for 반복문에서 각 얼굴의 면적(area())을 서로 비교하여 가장 넓은 사각형을 maxRect에 저장합니다.
  4. 결과 표시: 두 번째 반복문에서 rectangle() 함수를 사용해 가장 큰 얼굴 주위에 자홍색(magenta) 사각형을 그린 뒤, imshow()로 결과 창에 출력합니다.

실행 결과

C++와 OpenCV로 이미지에서 가장 큰 얼굴만 감지하는 방법