얼굴인식

Pywiki
180.81.64.102 (토론)님의 2021년 10월 1일 (금) 16:29 판 (→‎구현방법)
둘러보기로 가기 검색하러 가기

1 개요

얼굴추적을 한 후 해당 얼굴이 어떤 사람의 얼굴인지 파악하는 기술이다. 얼굴을 찾거나 따라가는 기술을 찾는다면 얼굴추적 문서를 참고하자.

2 구현방법

첫 번째 단계로 얼굴찾기를 수행해주어야 한다.

import dlib  # 얼굴인식
import cv2  # 이미지처리
import numpy as np  # 연산

detector = dlib.get_frontal_face_detector()  # 얼굴탐지모델
predictor = dlib.shape_predictor('shape_predictor_68_face_landmarks.dat')  # 얼굴 랜드마크 탐지 모델. 학습된 모델을 가져온다.
facerec = dlib.face_recognition_model_v1('models/dlib_face_recognition_resnet_model_v1.dat')  # 인식모델. 랜드마크에서 shape를 받아 구분한다.
# 위 모델로 특정인을 인식할 수 있다.

descs = np.load('img/descs.npy', allow_pickle=True)[()]
cap = cv2.VideoCapture(0)  # 영상 캡쳐. 경로 대신 0을 넣으면 웹캠이 켜진다.

dlib_face_recognition_reset_model 은 다음 링크를 통해 받자. 링크

위 과정에서 에러가 난다면 얼굴추적 문서를 참고하자.

2.1 얼굴 입력하기

분류할 얼굴을 특정 디렉터리 안에 그림파일로 넣고, 이들의 특징을 담은 넘파이 배열을 descs.npy에 저장한다.

이는 최초에 얼굴에 대해 교육할 때만 사용한다.

def educate():
    import os
    path_dir = 'C:\\Users\\id843\\PycharmProjects\\AI_practice\\img\\to_recognize\\'
    img_list = os.listdir(path_dir)
    people = {}
    for name in img_list:
        img_bgr = cv2.imread(path_dir + name)
        name = name.split('.')[0]  # 확장자를 쳐내고 앞의 이름만 따온다.

        face = detector(img_bgr)[0]  # 얼굴 하나만 받는다.
        dlib_shape = predictor(img_bgr, face)  # 특징점을 리턴받는다.
        face_descriptor = facerec.compute_face_descriptor(img_bgr, dlib_shape)
        people[name] =  np.array(face_descriptor)  # 연산을 위해 배열로 저장.

    np.save('img\descs.npy', people)

2.2 함수정의

의도 설명 방법
특징점을 배열로 반환하기 얼굴의 특징점을 찾아 배열로 반환한다.
def recognize_faces(img):
    '''얼굴의 특징점을 찾아 기존의 기억된 인물들과 대조한다'''
    faces = detector(img, 1)
    if len(faces) == 0:
        return np.empty(0)

    for k, face in enumerate(faces):
        shape = predictor(img, face)  # 주어진 얼굴의 특징점을 찾는다.
        face_descriptor = facerec.compute_face_descriptor(img, shape)

    result = {'name':'unkown', 'dist':0.6, 'color':(0,0,255)}  # 못찾았을 때의 기본값.
    for name, saved_desc in descs.items():  # 교육된 아이템에서 순회한다....
        dist = np.linalg.norm([face_descriptor] - saved_desc, axis=1)  # 인식된 데이터와 학습된 데이터를 비교.
        if dist < result['dist']:  # 일치값이 0.6보다 낮다면..(일반적으로 0.6이 잘 된다고 알려져 있음)
            result = {'name': name, 'dist': dist, 'color': (255, 255, 255)}

    cv2.putText(img, result['name'], org=(face.left(), face.top()), fontFace=cv2.FONT_HERSHEY_SIMPLEX,
                fontScale=1, color=result['color'], thickness=2)

2.3 실행

while True:  # 기본적으로 계속 진행
    ret, img = cap.read()  # 캡처한 영상을 프레임 단위로 읽는다.
    if not ret:  # 잘 찍히면 ret은 True를 반환한다.
        break  # 프레임이 없다면 종료.
    recognize_faces(img)
    cv2.imshow('window', img)  # 창에 해당하는 이미지를 띄운다.
    cv2.waitKey(1)  # 이게 있어야 창이 제대로 열린다.