소스 뷰어
하르 분류기를 통한 얼굴 검출의 구현¶
- 얼굴 영상에서 얼굴 영역과 눈 영역을 검출
- 얼굴 객체의 검출을 위해서cv2.CascadeClassifier() 함수를 사용하여 얼굴 및 눈 검출기를 로드하여 cv2.detectMultiScale() 함수를 사용하영 얼굴과 눈을 검출한다
하르 기반 분류기¶
- 얼굴과 얼굴이 아닌 것의 차이를 효율적으로 보여줄 수 있는 유사 하르 특징(Hear-line features)을 이용한 방법
- 유사 하르 특징은 하르 웨이브릿(Hear wavelet)과 비슷해 분여진 이름으로서, 위치, 모양, 크기에 따라 다양한 형태로 구성되어 있다. 그 특징값은 흰식 영역의 화소값의 합과 검은색 직사각형 영역의 화소값의 합의 차로 정의된다.
- 하르 기반 다단계(cascade) 분류기는 유사 하르 특징과 같은 매우 단순한 특징들을 조합하여 객체를 찾아낸다. 다단계(cascade)란 용어에서 알 수 있듯이, 여러 단계의 검출기를 순차적으로 사용한다. 처음에 간단한 검출기를 적용하고, 진행할수록 복잡한 검출기를 적용한다. 따라서 단순 검출기를 통과한 후보만 많은 시간이 걸리는 강력한 검출기가 적용되기 때문에 검출 속도를 크게 향상 시킬 수 있다.
- OpenCV의 cascade 분규기는 1000개 이상의 얼굴 영상과 10000개 이상의 얼굴이 아닌 영상을 사용하여 학습되었다. 이 과정을 일반적인 멀티코어 CPU를 장착한 컴퓨터에서 최대 일주일 정도의 시간이 소요된다. 다행히 OpenCV에서 미리 학습된 다양한 검출기를 제공한다. 따라서 필요한 종류의 파일을 로드하면 검출기를 사용하여 분류할 수 있다.
XML 검출기 목록¶
cascade classifer 분류기 | XML 파일명 | |
---|---|---|
Face detector (default) | haarcascade_frontalface_default.xml | |
Face detector (fast Harr) | haarcascade_frontalface_alt2.xml | |
Face detector (fast LBP) | haarcascade_frontalface.xml | |
Eye detector (default) | haarcascade_eye.xml | |
Eye detector (separate for left) | haarcascade_lefteye_2splits.xml | |
Eye detector (separate for right) | haarcascade_righteye_2splits.xml | |
Mouth detector | haarcascade_mcs_mouth.xml | |
Nose detector | haarcascade_mcs_nose.xml | |
Whole person detector | haarcascade_fullbody.xml |
import cv2, numpy as np
def preprocessing(no): # 검출 전처리
image = cv2.imread('data/face/%2d.jpg' %no, cv2.IMREAD_COLOR)
if image is None: return None, None
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # 명암도 영상 변환
gray = cv2.equalizeHist(gray) # 히스토그램 평활화
return image, gray
face_cascade = cv2.CascadeClassifier("data/haarcascade_frontalface_alt2.xml") # 정면 검출기
eye_cascade = cv2.CascadeClassifier("data/haarcascade_eye.xml") # 눈 검출기
image, gray = preprocessing(34) # 전처리
if image is None: raise Exception("영상 파일 읽기 에러")
faces = face_cascade.detectMultiScale(gray, 1.1, 2, 0, (100, 100)); # 얼굴 검출
if faces.any():
x, y, w, h = faces[0]
face_image = image[y:y + h, x:x + w] # 얼굴 영역 영상 가져오기
eyes = eye_cascade.detectMultiScale(face_image, 1.15, 7, 0, (25, 20)) # 눈 검출 수행
if len(eyes) == 2: # 눈 사각형이 검출되면
for ex, ey, ew, eh in eyes:
center = (x + ex + ew // 2, y + ey + eh // 2)
cv2.circle(image, center, 10, (0, 255, 0), 2) # 눈 중심에 원 그리기
else:
print("눈 미검출")
cv2.rectangle(image, faces[0], (255, 0, 0), 2) # 얼굴 검출 사각형 그리기
cv2.imshow("image", image)
else: print("얼굴 미검출")
cv2.waitKey(0)