위 논문에서 제안한 특징(feature)을 기반으로 비디오 또는 이미지에서 오브젝트를 검출하기 위해 사용됩니다.
직사각형 영역으로 구성되는 특징을 사용기 때문에 픽셀을 직접 사용할 때 보다 동작 속도가 빠릅니다.
찾으려는 오브젝트(얼굴)가 포함된 이미지와 오브젝트가 없는 이미지를 사용하여 Haar Cascade Classifier(하르 특징 분류기)를 학습시키고 분류기를 사용하여 오브젝트를 검출합니다.
알고리즘은 다음 4단계로 구성됩니다.
- Haar Feature Selection (하르 특징 선택)
- Creating Integral Images(적분 이미지 생성)
- Adaboost Training(adaboost 학습)
- Cascading Classifiers(특징 분류기)
하르 특징 선택
두개의 사각형으로 구성된 하르 특징 값은 각 사각형 내부에 있는 픽셀들을 합하여 검은색 영역에서 흰색 영역을 뺀 값 입니다. 두 사각형의 크기와 모양은 동일합니다.
세개의 사각형으로 구성된 하르 특징은 중앙에 있는 검은색 사각형 내부의 픽셀합에서 흰색 사각형 내부의 픽셀합을 뺀것입니다.
네개의 사각형으로 구성된 하르특징 값은 대각선에 위치한 영역간의 차이입니다.
적분 이미지 생성
하르 특징을 계산하려면 검은색 사각형과 흰색 사각형 내부 픽셀의 합을 구해야 합니다.
픽셀의 합을 구하는것을 빠르게 하기 위해서 적분 이미지( integral image)를 사용합니다.
큰 이미지라도 빠르게 지정한 영역의 픽셀의 합을 구할 수 있습니다.
사각형 D 내의 픽셀 합계는 4개의 배열 참조로 계산할 수 있습니다.
위치 1의 적분 이미지 값은 사각형 A의 픽셀 합계입니다. 위치2는 A+B, 위치3은 A+C, 위치4는 A+B+C+D입니다.
D 내의 합계는 4+1-(2+3)으로 계산할 수 있습니다.
adaboost 학습
16만개 이상의 하르 특징값이 도출되는데 얼굴 검출을 하는데 의미있는 값만 추출하기 위해서 Adaboost를 사용합니다.대부분의 값은 의미없는 특징이고아래 같은 눈 주위 특징만 의미있는 특징입니다.가로방향으로 검은색 흰색 영역이 있는 특징은 눈 부분과 눈 아래부분 특징을 나타냅니다.세로방향 특징은 양쪽 눈과 코의 특징을 나타냅니다.
최적의 특징을 선택하기 위해 모든 학습 이미지에 특징을 적용합니다.
각 특징에 대해 얼굴이 포함된 이미지와 얼굴이 없는 이미지를 분류하기 위한 최적의 threshold를 찾습니다.
( 흰색 영역과 검은색 영역의 차이가 일정 임계값 이상이면 얼굴을 위한 특징이라 보는 겁니다.
얼굴이 아닌 영역에서는 두 영역간의 차이가 거의 없을거라고 보고 만든 알고리즘입니다. )
이 때 잘못 분류될 가능성이 있기 때문에 에러률이 낮은 특징을 선택해야 합니다.
즉 얼굴이 포함된 이미지와 얼굴이 없는 이미지를 정확하게 분류할 수 있는 특징을 선택하는 것입니다.
다음 과정을 반복합니다.
1) 처음에는 모든 하르 특징이 똑같은 가중치를 갖습니다.
2) 모든 하르 특징에 대해 학습 데이터 세트를 사용하여 분류한 결과 각 하르 특징의 에러률을 계산하고
잘못 분류하는 하르 특징에는 가중치를 증가시킵니다.
결과적으로 성능 좋은 하르 특징은 낮은 에러률을 갖게 됩니다.
낮은 에러률을 보이는 하르 특징을 선택하게 됩니다.
3) 다음을 만족할 때까지 2)번을 반복합니다.
요구하는 정확성 또는 요구하는 에러율 획득 또는 요구하는 개수의 특징을 발견
최종 분류자는 약 분류자들에 대한 가중치 합입니다.
개별 특징으로는 이미지를 분류할 수 없어 약 분류자라고 부릅니다.
하지만 약 분류자를 여러개 묶으면 이미지를 분류할 수 있게 됩니다.
Adaboost를 통해 160,000개의 특징은 6000개의 특징으로 줄어들게 됩니다.
Cascade Classifier
이제 이미지를 준비하여 24 x 24 크기의 윈도우를 사용하여 6000개의 하르 특징을 적용하여 얼굴을 검출하면 됩니다.
하지만 이렇게 하면 계산량이 너무 많기 때문에 비효율적입니다.
이미지의 대부분의 공간은 얼굴이 없는 영역입니다. 그래서 현재 윈도우가 있는 영역이 얼굴 영역인지를 단계별로 체크하는 방법을 사용합니다.
낮은 단계에서는 짧은 시간에 얼굴 영역인지 판단하게 되며
상위 단계로 갈수록 좀더 시간이 오래걸리는 연산을 수행합니다.
이 방식을 Cascade Classifier라고 합니다.
윈도우가 이미지 위를 이동할 때마다 6000개의 특징을 모두 적용하지 않고 여러 단계의 그룹으로 묶어 사용하는 겁니다.
첫번째 단계의 특징에서 얼굴 영역이 아니라는 판정이 나면 바로 다음 위치로 윈도우를 이동하며
첫번째 단계의 특징에서 얼굴 영역이라는 판정이 내려지면 현재 윈도우가 위치한 곳에 다음 단계의 특징을 적용합니다.
눈 분류기와 정면얼굴 분류기 파일 입니다.
import cv2
import numpy as np
def nothing(x):
pass
frame = cv2.imread('Haar Cascades face detection/face.jpg')
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
face_cascade = cv2.CascadeClassifier("Haar Cascades face detection/haarcascade_frontalface_default.xml")
cv2.namedWindow("Frame")
cv2.createTrackbar("Neighbours", "Frame", 5, 20, nothing)
while True:
neighbours = cv2.getTrackbarPos("Neighbours", "Frame")
faces = face_cascade.detectMultiScale(gray, 1.3, neighbours)
for rect in faces:
(x, y, w, h) = rect
frame = cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
cv2.imshow("Frame", frame)
key = cv2.waitKey(1)
if key == 27:
break
cap.release()
cv2.destroyAllWindows()
'영상처리 > 기초' 카테고리의 다른 글
Face swapping-Delaunay Triangulation(part 2) 들로네 삼각분할 (19) | 2023.01.05 |
---|---|
Face swapping (part1) 얼굴 교환 (5) | 2023.01.05 |
YOLO 객체 검출 알고리즘 (17) | 2023.01.04 |
cv2.error: OpenCV(4.7.0) D:\a\opencv-python\opencv-python\ (5) | 2023.01.03 |
이미지 다운 샘플링 (4) | 2022.12.23 |