본문 바로가기
SWE/Learning Diary

[C++/OpenCV]하르분류기_얼굴 검출 구현

by S나라라2 2018. 4. 30.
반응형

Haar알고리즘 설명하는 링크


https://blog.naver.com/seokcrew/30089288274




책 : 정성환,배종욱 - OpenCV로 배우는 영상 처리 및 응용 / 생능 출판


하르 분류기를 이용하여 얼굴 검출 구현해보기


Haar-like features란 위치, 모양, 크기에 따라 다양한 형태로 구성되어 있는데, 흰색 영역의 화소값의 합과 검은색 직사각형 영역의 화소값의 합의 차로 특징값을 구한다.

캐스케이드란 여러 개의 검출기를 순차적으로 사용한다. 처음에 간단한 검출기를 적용하고, 진행할수록 복잡한 검출기를 적용한다. 따라서 단순 검출기를 통과한 후보에만 시간이 많이 걸리는 강력한 검출기가 적용되기 때문에 검출 속도를 크게 향상시킬 수 있다.

OpenCV는 다양한 하르 기반 검출기를 제공하고 있다. openCV 디렉터리 아래 의 /sources/data/harrcascades 폴더에 위치한다.


- preprocessing 헤더 파일 작성

1.load_casecade() 함수를 이용하여 검출기 파일이 있는 경로를 지정하고, 해당하는 xml 파일을 인수로 입력받아서 검출기를 로드한다.

2.CascadeClassifier::detectMultiScale() 함수를 사용하여 객체를 검출한다.

3.입력된 컬러 영상에 대해 전처리를 수행한다. 전처리의 과정은 컬러 영상을 명암도 영상으로 만들고 히스토그램 평활화를 통해 간단하게 영상의 화질을 개선한다.


- 메인 함수 작성

1. 얼굴 및 눈 영역 검출 cv::CascadeClassifier::detectMultiSale()

2. 얼굴 기울기 계산 및 보정 cv::fastAtan2() cv::getRotationMatrix2D()


>preprocessing 헤더파일 작성 ( 검출기 로드  & 전처리 과정 )

#include 
using namespace cv;
using namespace std;

void load_cascade(CascadeClassifier& cascade, string fname) {
	String path = "C:/opencv/sources/data/haarcascades/"; // 검출기 폴더
	String full_name = path + fname;

	CV_Assert(cascade.load(full_name)); // 분류기 로드 및 예외 처리
}

Mat preprocessing(Mat image) {
	Mat gray;
	cvtColor(image, gray, CV_BGR2GRAY);
	equalizeHist(gray, gray);

	return gray;
}


> 얼굴 검출 main 함수 작성

#include "preprocess.hpp" // 검출기 로드 및 전처리 함수

Point2d calc_center(Rect obj) {  // 사각형 중심 계산
	Point2d c = (Point2d)obj.size() / 2.0;
	Point2d center = (Point2d)obj.tl() + c;
	return center;
}

int main() {
	CascadeClassifier face_cascade, eyes_cascade;
	load_cascade(face_cascade, "haarcascade_frontalface_alt2.xml"); // 정면 얼굴 검출기
	load_cascade(eyes_cascade, "haarcascade_eye.xml"); // 눈 검출기

	Mat image = imread("../face/59.jpg", IMREAD_COLOR); // 얼굴 영상 로드
	CV_Assert(image.data);
	Mat gray = preprocessing(image); // 전처리

	vector faces, eyes;
	vector eyes_center;
	face_cascade.detectMultiScale(gray, faces, 1.1, 2, 0, Size(100, 100)); //얼굴 검출

	if (faces.size() > 0) {  // 얼굴 사각형 검출되면
		//눈 검출 수행
		eyes_cascade.detectMultiScale(gray(faces[0]), eyes, 1.15, 7, 0, Size(25, 20));

		if (eyes.size() == 2) {  // 눈 사각형이 검출되면
			for (size_t i = 0; i < eyes.size(); i++) {
				Point2d center = calc_center(eyes[i] + faces[0].tl()); // 중심점 계산
				circle(image, center, 5, Scalar(0, 255, 0), 2); // 눈 중심에 원 그리기
			}
		}

		rectangle(image, faces[0], Scalar(255, 0, 0), 2); // 얼굴 검출 사각형 그리기
		imshow("image", image);
		waitKey();
	}
	return 0;
}



반응형