본문 바로가기

Machine Learning/영상처리

OpenCV로 얼굴인식하기

OpenCV는 ComputerVision 관련 프로그래밍을 쉽게 할 수 있도록 도와주는 open Library이다. OpenCV는 영상처리, 3D 구성, 추적,기계학습, 인식 그리고 딥러닝 까지 유용한 기능이 아주 많으며 상업적인 용도로도 무료이다


 

Haar 특징기반 다단계 분류자(Feature-based Cascade Classifiers)를 이용한 물체 검출은 Paul Viola와 Michael Jones이 2001년에 발표한 논문, “Rapid Object Detection using a Boosted Cascade of Simple Features”에서 제안된 효과적인 물체 검출방법 이다. 이는 검출할 대상이 되는 물체가 있는 이미지와 없는 이미지(각각을 Positive Image와 Negative Image라고 함)를 최대한 많이 활용해서 다단계 함수를 훈련시키는 기계학습 방식이다

 

이 글에서는 검출할 대상을 얼굴로 시험해 보자. 처음에, 이 알고리즘은 분류자(Classifier)를 훈련시키기 위해 매우 많은 훈련용 이미지가 필요하다. 이 이미지는 앞서 언급한 Positive와 Negative 이미지다. 다음 단계는 특징들(Features)를 추출해야 하는데. 이를 위해, 아래 그림에서의 Haar 특징이 사용된다. 이 각 특징은 하얀색 사각형에서의 픽셀값의 합을 검은색 사각형 영역의 픽셀 값의 합에서 뺀 값이다.

 

이미지를 스캔하면서 위치를 이동시키는 인접한 직사각형들의 영역내에 있는 픽셀의 합의 차이를 이용하는 것이다. 사각 영역 내부의 픽셀들을 빨리 더하기 위해 적분 이미지를 사용한다.

 

Haar의 특징에는

  • 두 개의 사각형으로 구성된 하르 특징의 값은 두 사각 영역 내부에 있는 픽셀들의 합하여 검은색 영역의 합에서 흰색 영역의 합을 빼서  구한 것이다. 두 사각형의 크기와 모양은 동일하다.

  • 4개의 사각형으로 구성된 하르 특징은 대각선에 위치한 영역간의 차이를 구하는 것이다


Adaboost Training

 

24x24 이미지에서 160000개 이상의 특징이 검출되었는데 이를 줄일 필요가 있다. 이때 처리 성능을 향상하기 위하여 Adaboosts를 사용한다.

앞에서 하르특징으로 구한 특징은 대부분 무의미하다.

 

  • 가로 방향으로 검은색 사각 영역과 흰색 사각 영역이 있는 특징의 경우에는  코와 빰보다 눈 부분이 더 어둡다는 특성을 사용힌다. 

  • 세로 방향으로 흰색 사각영역이 있고 좌우에 검은색 사각 영역이 있는 특징의 경우에는 중앙에 있는 코보다 양쪽에 있는 눈 부분이 더 어둡다는 특성을 사용한다

  • 최적의  특징을 선택하기 위해 모든 학습 이미지에  특징을 적용합니다. 각  특징에 대해 얼굴이 포함된 이미지와 얼굴이 없는 이미지를 분류하기 위한 최적의 임계값(threshold)을  찾는다

즉 얼굴이 포함된 이미지와 얼굴이 없는 이미지를 정확하게 분류할 수 있는 특징을 선택하는 것이다

Adaboost를 통해 160,000개의 특징은 6000개의 특징으로 줄어들게 된다. 

 


얼굴을 인식해보자.

 

샘플이미지이다

 

import cv2
import sys
# 입력 파일 지정하기
image_file = "./pakutas/photo1.jpg"
# 캐스케이드 파일의 경로 지정하기 --- (※1)
cascade_file = "haarcascade_frontalface_alt.xml"
# 이미지 읽어 들이기 --- (※2)
image = cv2.imread(image_file)
# 그레이스케일로 변환하기
image_gs = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 얼굴 인식 특징 파일 읽어 들이기 --- (※3)
cascade = cv2.CascadeClassifier(cascade_file)
# 얼굴 인식 실행하기
face_list = cascade.detectMultiScale(image_gs,
    scaleFactor=1.1,
    minNeighbors=1,
    minSize=(150,150))
if len(face_list) > 0:

 

캐스케이드 파일은 OpenCV가 설치될 때 자동으로 share 폴더에 복사된다. 따라서 프로그램의 ※1에서 경로 지정을 알맞게 설정해줘야 한다 OpenCV에서 얼굴을 인식할 때는 얼굴 인식 전용 캐스케이드 파일을 지정해야 한다. 이 책에서는 캐스케이드 파일인 "harrcascade_frontalface_alt.xml"을 예제 프로그램과 같은 경로에 배치하고 실행하였다.

 

※3 에서는 얼굴인식 전용 캐스케이드 파일을 읽어 들이고 얼굴인식을 실핸한다. detectMultiScale() 메서드가 얼굴을 인식하는 부분인데, 매개변수 minSize에 지정한 튜플(150, 150)은 얼굴을 인식할 때 150x150 픽셀 이하의 크기를 무시하겠다는 설정이다. 현재 이미지에서는(1,1)로 변경해도 상관없지만 너무 작게 지정하면 다른 이미지를 사용할 때 배경 등을 얼굴로 잘못 인식하는 경우도 있다.

 

    # 인식한 부분 표시하기 --- (※4)
    print(face_list)
    color = (0, 0, 255)
    for face in face_list:
        x,y,w,h = face
        cv2.rectangle(image, (x,y), (x+w, y+h), color, thickness=8)
    # 파일로 출력하기 --- (※5)
    cv2.imwrite("facedetect-output.PNG", image)
else:
    print("no face")

※4 에서는 인간의 얼굴이라고 인식한 범위좌표에 사각형을 그린다 ※5 에서는 결과를 파일로 출력한다.

 

 

얼굴을 인식한 부분에 사격형이 표시되있다.


얼굴에 모자이크 걸기

원본이미지

 

    quit()
# 확인한 부분에 모자이크 걸기 -- (※4)
print(face_list)
color = (0, 0, 255)
for (x,y,w,h) in face_list:
    # 얼굴 부분 자르기 --- (※5)
    face_img = image[y:y+h, x:x+w]
    # 자른 이미지를 지정한 배율로 확대/축소하기 --- (※6)
    face_img = cv2.resize(face_img, (w//mosaic_rate, h//mosaic_rate))
    # 확대/축소한 그림을 원래 크기로 돌리기 --- (※7)
    face_img = cv2.resize(face_img, (w, h), 
        interpolation=cv2.INTER_AREA)
    # 원래 이미지에 붙이기 --- (※8)
    image[y:y+h, x:x+w] = face_img
# 렌더링 결과를 파일에 출력
cv2.imwrite(output_file, image)

 

※4 이전의 코드는 아까와 같으므로 생략하겠다. ※4에서 얼굴에 모자이크를 거는 방법은 간단하다. 이미지를 작게 만들고 다시 원래 크기로 돌리는 것인데, 이미지를 작게 만들면 이미지의 화소가 줄고 다시 원래대로 돌리면 줄어든 화소 상태로 다시 확대되면 점을 이용한 것이다.

 

※5에서는 이미지의 일부분을 잘라낸다 OpenCV는 이처럼 배열 형태로 이미지의 일부분을 잘라낼 수 있다 이는 Numpy의 배열이므로 배열 차원의 수를 줄이거나 할꺼번에 계산한다거나 하는 작업이 굉장히 쉽다.

 

※6 에서는 잘랐던 얼굴 부분의 이미지 크기를 변경한다 이미지 크기를 변경할 때는 cv2.resize()함수를 이용한다.

※7 에서는 축소한 이미지를 이전 크기로 되돌리는다 이때, 어떻게 크기를 변경할지 interpolation매개변수로 지정한다. 

cv.INTER_LINEAR를 사용하면 모자이크의 각이 명확하게 보이지 않게 된다.

 

결과가 아주 좋다

'Machine Learning > 영상처리' 카테고리의 다른 글

이미지 OCR  (0) 2020.07.18
규동 메뉴 이미지 판정하기  (0) 2020.07.16
CNN으로 이미지 분류하기  (1) 2020.07.15
유사한 이미지 판별 그리고 Average Hash  (0) 2020.07.15