본문 바로가기
ੈ✩‧₊˚Computer Science/컴퓨터비전

[OpenCV] Face detection (얼굴 검출)

by 샨샨 2020. 11. 18.
반응형

컴퓨터가 물체를 어떻게 찾아낼까?

  • training stage : 많은 사진을 모아 물체를 나타내는 특징을 찾아내기 ( 학습시킴 )

  • test stage : input image로 부터 특징을 추출해내기

Harr-like feaure

-모든 사람은 얼굴이 다르게 생겼지만 그 패턴은 같음 (눈,코,입)

- 사람의 얼굴 위에 흑백의 사각형을 겹쳐 놓은 다음 밝은 영역에 속한 픽셀 값들의 평균에서 어두운 영역에 속한 픽셀값들의 평균의 차이를 구한다. (어두운 영역에 속한 픽셀값의 평균 - 밝은 영역에 속한 픽셀값의 평균을 계산하고 임계값 이상인 것을 찾으면 된다)

- feature의 크기와 모양, 위치는 다양할 수 있다. (검은색부분과 흰색부분의 크기는 같아야 함)

Boosting : weak-learner 로 strong- learner를 만드는 것

Adaptive : weaj-learner의 가중치를 다르게 조절해 주는 것

동그라미 = face 세모 = non face 

-> 동그라미인데, 인식되지 않는 부분을 가중시켜 인식하게 만든다.

 

cascade classifier (다단계 검출)

weak-learner을 여러번 사용해서 strong-learner을 생성하기

1. cascade 2.3>2>1

□ 여러 단계를 거치면서 non-face region이 쉽게 제거된다.

 

integral image (적분 영상)

: 이전 픽셀의 값을 모두 더해 현재 픽셀을 만드는 것

  • integral image를 활용하면 픽셀에 접근하지 않고도 계산량을 줄일 수 있는 장점이 있다.
  • openCV에 내장되어 있는 face detection 알고리즘은 Haar-like feature을 활용하는데, 이를 계산하기 위해서는 특정 영역의 픽셀들의 합을 계산하기 때문에 integral image가 필요하다.
  • 맨 왼쪽과 맨 위쪽은 0으로 채움

 

opencv 의 face detection 알고리즘

 

void cv::CascadeClassifief::detectMultiScale(InputArray image, std::vector<Rect> & objects, std::vector <int> & numDetections, double scaleFactor = 1.1, int minNeighbors = 3, int flags =0, Size minSize= Size(), Size maxSize = Size() )

■ input이미지에서 크기가 다른 object를 검출(detect)하는 함수

■ haarcascade_frontalface_alt.xml 이용

 

argument 설명

▨ InputArray image : 바로 검출하고자 하는 원본 이미지

▨ std::vector<Rect> & objects : object에 검출된 이미지가 채워짐 ( 얼굴을 인식하여 그려지는 rectangle 변수 이름 )

 std::vector <int> & numDetections : detect되는 object의 개수

double scaleFactor : 얼굴의 크기가 다양하기 때문에 영상의 크기 조절

int minNeighbors : 여러 스케일의 크기에서 minNeighbors 횟수 이상 검출된 object는 valid하게 검출( 최소한의 중복된 얼굴 검출 횟수)

int flags : 안씀

Size minSize : minSize 보다 작은 사이즈의 물체는 무시

 Size maxSize : maxSize 보다 큰 사이즈의 물체는 무시

 

이를 이용한 얼굴 인식 예제 코드

#include "cv.hpp"
#include <iostream>

using namespace cv;
using namespace std;

int main(){
    CascadeClassifier face_classifier;
    Mat frame, grayframe;
    vector <Rect> faces;
    int i;

    VideoCapture cap(0);

    if(!cap.isOpened()){
        cout << "Could not open camera" << endl;
        return -1;
    }

    face_classifier.load("../haarcascade_frontalface_alt.xml");

    while(true){
        cap >> frame;

        cvtColor(frame, grayframe, COLOR_BGR2GRAY);

        face_classifier.detectMultiScale(
            grayframe, faces, 1.1, 3, 0, Size(30,30)
        );

        for(i=0; i< faces.size(); i++){
            Point lb(faces[i].x + faces[i].width, faces[i].y + faces[i].height);
            Point tr(faces[i].x ,faces[i].y);
            rectangle(frame,lb,tr,Scalar(0,255,0),3,4,0);
        }

        imshow("Face Detection", frame);
        if(waitKey(33)==27) break;
    }
}

 

 

반응형