과거 얼굴인식은 첩보영화나 CSI와 같은 드라마에서 범죄자를 찾는데 활용되는 신기술로 인식되었으나, 머신러닝과 하드웨어의 발전으로 이젠 일상에서 쉽게 접할 수 있게 되었습니다. 현재 얼굴인식 기술은 크게 탐지(Detection)과 인식(Identification)으로 나뉘고 있습니다. 페이스북이나 인스타그램에 사진을 업로드할때 얼굴을 찾아주는 탐지 기술, 아이폰 보안 기술로 활용되는 Face ID는 인식 기술이 아마 대표적이고 우리에게 친숙한 얼굴 인식 응용 기술이지 않을까 싶습니다. 이번 포스팅에서는 비교적 과거 기술이지만 간단하게 CPU에서도 연산이 가능한 얼굴 탐지 알고리즘 Cascading classifiers를 OpenCV를 이용하여 구현해보록 하겠습니다.
1. Haar Cascade 분류기 불러오기
import cv2
# 가중치 파일 경로
cascade_filename = 'haarcascade_frontalface_alt.xml'
# 모델 불러오기
cascade = cv2.CascadeClassifier(cascade_filename)
OpenCV에서 기본 라이브러리로 제공하는 Haar Cascade는 기계학습을 이용한 객체 탐지 알고리즘입니다. CNN이나 RSTM 등의 신경망이 아닌, 하르 특징 (Haar Features) 계산을 통해 객체를 찾습니다. 사전 학습된 분류기 (haarcascade_frontalface_alt.xml) 를 로드한 뒤, cv2를 통해 분류기를 생성해줍니다.
2. Test 영상 & 사진 불러오기
# 영상 파일
cam = cv2.VideoCapture('sample.mp4')
# 사진 파일
img = cv2.imread('sample.jpg')
# 영상 재생
def videoDetector(cam,cascade):
while True:
# 캡처 이미지 불러오기
ret,img = cam.read()
# 영상 압축
img = cv2.resize(img,dsize=None,fx=0.75,fy=0.75)
# 그레이 스케일 변환
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 사진 출력
def imgDetector(img,cascade):
img = cv2.resize(img,dsize=None,fx=0.5,fy=0.5)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
영상 또는 사진 속 객체를 인식하기 위해, 기본 소스를 불러옵니다. Cascading classifiers는 gray scale (흑백 영상)으로 변환된 뒤, 특징맵 분류기에 입력되므로 cvtColor를 통해 영상 전처리를 진행합니다. 모든 과정은 openCV 함수를 사용하시면 되며 이전 포스팅을 참고하시면 보다 쉽게 이해하실 수 있습니다.
3. 얼굴 탐지 알고리즘 적용
# cascade 얼굴 탐지 알고리즘
results = cascade.detectMultiScale(gray, # 입력 이미지
scaleFactor= 1.5,# 이미지 피라미드 스케일 factor
minNeighbors=5, # 인접 객체 최소 거리 픽셀
minSize=(20,20) # 탐지 객체 최소 크기
)
# 결과값 = 탐지된 객체의 경계상자 list
for box in results:
# 좌표 추출
x, y, w, h = box
# 경계 상자 그리기
cv2.rectangle(img, (x,y), (x+w, y+h), (255,255,255), thickness=2)
detectMultiScale을 통해 객체 탐지 알고리즘을 실행해줍니다. 여기서 scaleFactor는 쉽게 말해, 그림 2와 같이 객체 탐지를 위해 이미지를 다양한 크기로 변형을 주는데 이때의 변화 정도율정도 생각하시면 될것같습니다. scaleFactor 값이 커지게 될경우, 큼직큼직하게 변화시켜가며 분석하기때문에 탐지 성공율은 떨어지지만, 연산량은 감소하게됩니다.
4. 최종 응용 코드
# -*- coding: utf-8 -*-
"""
Created on Wed Nov 4
@author: jongwon Kim
Deep.I Inc.
"""
import cv2
import timeit
# 영상 검출기
def videoDetector(cam,cascade):
while True:
start_t = timeit.default_timer()
# 알고리즘 시작 시점
""" 알고리즘 연산 """
# 캡처 이미지 불러오기
ret,img = cam.read()
# 영상 압축
img = cv2.resize(img,dsize=None,fx=1.0,fy=1.0)
# 그레이 스케일 변환
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# cascade 얼굴 탐지 알고리즘
results = cascade.detectMultiScale(gray, # 입력 이미지
scaleFactor= 1.1,# 이미지 피라미드 스케일 factor
minNeighbors=5, # 인접 객체 최소 거리 픽셀
minSize=(20,20) # 탐지 객체 최소 크기
)
for box in results:
x, y, w, h = box
cv2.rectangle(img, (x,y), (x+w, y+h), (255,255,255), thickness=2)
""" 알고리즘 연산 """
# 알고리즘 종료 시점
terminate_t = timeit.default_timer()
FPS = 'fps' + str(int(1./(terminate_t - start_t )))
cv2.putText(img,FPS,(30,30),cv2.FONT_HERSHEY_SIMPLEX,1,(255,255,255),1)
# 영상 출력
cv2.imshow('facenet',img)
if cv2.waitKey(1) > 0:
break
# 사진 검출기
def imgDetector(img,cascade):
# 영상 압축
img = cv2.resize(img,dsize=None,fx=1.0,fy=1.0)
# 그레이 스케일 변환
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# cascade 얼굴 탐지 알고리즘
results = cascade.detectMultiScale(gray, # 입력 이미지
scaleFactor= 1.5,# 이미지 피라미드 스케일 factor
minNeighbors=5, # 인접 객체 최소 거리 픽셀
minSize=(20,20) # 탐지 객체 최소 크기
)
for box in results:
x, y, w, h = box
cv2.rectangle(img, (x,y), (x+w, y+h), (255,255,255), thickness=2)
# 사진 출력
cv2.imshow('facenet',img)
cv2.waitKey(10000)
# 가중치 파일 경로
cascade_filename = 'haarcascade_frontalface_alt.xml'
# 모델 불러오기
cascade = cv2.CascadeClassifier(cascade_filename)
# 영상 파일
cam = cv2.VideoCapture('sample.mp4')
# 이미지 파일
img = cv2.imread('sample.jpg')
# 영상 탐지기
videoDetector(cam,cascade)
# 사진 탐지기
# imgDetector(cam,cascade)
지난 포스팅에서 다룬 FPS 측정 알고리즘을 추가로 응용해봤습니다. i7 칩셋에서도 scaleFactor 값을 1.05 정도로 낮춰주면 프레임 드랍이 10 ~ 20 정도로 심하게 발생합니다. 간단한 어플리케이션에서는 활용도가 높을 수 있겟지만 보다 높은 검출율이 요구된다면 신경망을 적용한 최신 기법으로 활용해야할 것같습니다. 다음 포스팅에서는 성별, 나이 분류기를 통해 탐지된 얼굴을 기반으로 추정해보도록 하겠습니다.
5. 참고
http://docs.opencv.org/4.1.0/d7/d8b/tutorial_py_face_detection.html
www.pyimagesearch.com/2018/02/26/face-detection-with-opencv-and-deep-learning/
6. 나이&성별 예측기
Your Best AI Partner DEEP.I
Jetson 시리즈 & 라즈베리 기반 엣지 컴퓨팅 시스템 제작
인공지능 프로젝트 제작 외주 및 상담
E-mail: contact@deep-i.ai
Site: www.deep-i.ai
'Python > Python' 카테고리의 다른 글
[Python] 파이썬을 이용한 다층신경망 (Multi-Layer Perceptron: MLP) 구현하기 (XOR 문제) (0) | 2020.11.28 |
---|---|
[Python] PyTicToc 파이썬에서 경과 시간 간편하게 측정하기 (0) | 2020.11.25 |
[Python] configparser를 이용하여 config (설정값 ini 파일) 관리하기 (0) | 2020.11.01 |
[Python] OpenCV 실시간으로 영상의 Frame Rate (FPS) 확인하기 (1) | 2020.10.23 |
[Python] OpenCV를 이용한 영상 재생과 Frame Rate (FPS) 조절 (1) | 2020.07.12 |