본문 바로가기
프로그램 활용/인공지능(AI)

[자료수집] 안면인식 시스템(기본코드)

by 3604 2022. 7. 17.
728x90

- CAM으로 화면을 받아와서 영상에 비친 인물과 데이터 사이의 일치도를 비교하는 파이썬 코드입니다.

- dlib, opencv, face-recognition으로 만들었습니다.

- 보시면 고도화할 부분이 많습니다만 안면인식의 가장 기본적인 형태입니다.

성능이 그렇게 좋다고 할수 없고, 최적화도 안된 상태로, 라이브러리를 사용한 외부 시스템 구성이 어떤건지만 알아두세요.

- 내부 데이터 분석 기술은 딥러닝이 아닌 머신러닝인데, 딥러닝으로 구현하시려면 샴 네트워크와 Triplet Loss에 대해 이해하셔야합니다.(더불어 인코딩 모델에 따른 Latent vector에 대한 manifold hypothesis에 대한 이해 필요.)

- 이전에도 공개한 코드를 보다 쉽게 설치 가능하게 정리한 글입니다.

 

0. 준비

파이썬 설치 및 파이참 설치

이후 파이참에서 프로젝트를 생성 후 프로젝트 setting에서 인터프리터 설정.

인터프리터 설정에서 라이브러리 추가로 아래 라이브러리 설치

pip,

cmake,

numpy,

opencv-python, 

dlib(이건19.18버전으로 설치),

face-recognition(Adam Geitgey)

 

설치법은 wiserloner.tistory.com/1123에 자세히 나와있습니다.

 

1. 코드

파이썬 파일을 하나 만들고,

import cv2
import numpy as np
import face_recognition
import os

# 설정
path = 'C:/Users/pps/Pictures/Camera Roll/pass'
images = []
classNames = []
myList = os.listdir(path)

# 사진 디렉토리 내 이미지 경로 리스트 추출
for cl in myList:
    curImg = face_recognition.load_image_file(f'{path}/{cl}')
    images.append(curImg)
    classNames.append(os.path.splitext(cl)[0])
print(classNames)


# 각 사진별 인코딩 함수
def find_encodings(image_paths):
    encode_list = []
    for image_path in image_paths:
        encode = face_recognition.face_encodings(image_path)[0]
        encode_list.append(encode)
    return encode_list


# 인코딩 리스트 받기
encodeListKnown = find_encodings(images)
print(f'Encoding Complete {len(encodeListKnown)}')

# 캠 영상 받아서 처리
cap = cv2.VideoCapture(0)

while True:
    success, cap_img = cap.read()
    imgS = cv2.resize(cap_img, (0, 0), None, 0.25, 0.25)
    imgS = cv2.cvtColor(imgS, cv2.COLOR_BGR2RGB)

    # 캠 얼굴 인코딩
    faceCurFrame = face_recognition.face_locations(imgS)
    encodesCurFrame = face_recognition.face_encodings(imgS, faceCurFrame)

    # 캠 얼굴과 메모리상 인코딩 데이터간의 비교
    for encodeFace, faceLoc in zip(encodesCurFrame, faceCurFrame):
        matches = face_recognition.compare_faces(encodeListKnown, encodeFace)
        faceDis = face_recognition.face_distance(encodeListKnown, encodeFace)

        matchIndex = np.argmin(faceDis)

        if matches[matchIndex]:
            name = classNames[matchIndex].upper()

            y1, x2, y2, x1 = faceLoc
            y1, x2, y2, x1 = y1*4, x2*4, y2*4, x1*4
            cv2.rectangle(cap_img, (x1, y1), (x2, y2), (0,255,0),2)
            cv2.rectangle(cap_img, (x1, y2-35), (x2, y2), (0,255,0), cv2.FILLED)
            cv2.putText(cap_img, name, (x1+6, y2-6), cv2.FONT_HERSHEY_COMPLEX, 1, (255,255,255), 2)
        else:
            name = '???'

            y1, x2, y2, x1 = faceLoc
            y1, x2, y2, x1 = y1 * 4, x2 * 4, y2 * 4, x1 * 4
            cv2.rectangle(cap_img, (x1, y1), (x2, y2), (0, 255, 0), 2)
            cv2.rectangle(cap_img, (x1, y2 - 35), (x2, y2), (0, 255, 0), cv2.FILLED)
            cv2.putText(cap_img, name, (x1 + 6, y2 - 6), cv2.FONT_HERSHEY_COMPLEX, 1, (255, 255, 255), 2)

    cv2.imshow('cam', cap_img)
    cv2.waitKey(1)

를 입력하기만 하면 끝.

모르는 인물이 나오면 ???으로 뜨고,

데이터베이스(여기선 이미지파일) 안에 있는 인물은 이미지 파일 이름으로 나옵니다.

path에, 인물 얼굴 이미지를 모아두고, 새 인물을 등록할 때에는 저기에 얼굴 이미지를 넣으면 됩니다.

 

 

// 일단 이미지 파일에서 또다시 인코딩을 해야하니, 기존 데이터 저장은 이미 인코딩된 정보를 저장하는 것이 여러모로 좋습니다.

그리고 프로세스를 잘 파악해서 원하는 기능(방문일시 DB 저장)등을 할수있고,

이것만 사용하는게 아니라 다른 모델과 연계도 가능하죠.

 

// 핵심이 되는 기술은 다름아닌 얼굴을 인식하는 dlib과, 그 얼굴 특징을 인코딩하고 유사도를 파악하는 face_recognition 부분으로, 이게 라이센스가 어떻게 될지는 모르지만 일단 실용적이긴 합니다.

다만, 이 부분을 보다 고도화 하거나 하려면 데이터 분석 기술이 필요하니 참고하세요. (즉, 시스템 고도화를 하려면 위 코드 프로세스를 변경하고, 인식 고도화를 하려면 자체 모델 훈련을 할줄 알아야함.)

728x90